You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by GitBox <gi...@apache.org> on 2019/01/03 12:13:45 UTC
[GitHub] zshshr closed pull request #1999: merge code to master
zshshr closed pull request #1999: merge code to master
URL: https://github.com/apache/incubator-weex/pull/1999
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/WeexSDK.podspec b/WeexSDK.podspec
index 2f47a803fb..2a2b5aa700 100644
--- a/WeexSDK.podspec
+++ b/WeexSDK.podspec
@@ -47,7 +47,13 @@ Pod::Spec.new do |s|
'weex_core/Source/third_party/**/*.{h,hpp,m,mm,c,cpp,cc}',
'weex_core/Source/include/**/*.{h,hpp,m,mm,c,cpp,cc}'
s.exclude_files = 'weex_core/Source/**/*android.{h,hpp,m,mm,c,cpp,cc}',
- 'weex_core/Source/core/network/android/'
+ 'weex_core/Source/base/android',
+ 'weex_core/Source/base/crash',
+ 'weex_core/Source/base/utils',
+ 'weex_core/Source/third_party/IPC',
+ 'weex_core/Source/core/network/android/',
+ 'weex_core/Source/include/JavaScriptCore/',
+ 'weex_core/Source/include/wtf'
s.private_header_files = 'ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.h'
s.public_header_files = 'ios/sdk/WeexSDK/Sources/WeexSDK.h',
diff --git a/android/sdk/assets/weex-main-jsfm.js b/android/sdk/assets/weex-main-jsfm.js
index a603e0ac5a..20d41765a1 100644
--- a/android/sdk/assets/weex-main-jsfm.js
+++ b/android/sdk/assets/weex-main-jsfm.js
@@ -1,2 +1,2 @@
-(this.nativeLog||function(e){console.log(e)})("Start JS Framework 0.29.1, Build at 2018-12-19 16:07. (Vue: 2.5.16-weex.5, Rax: 0.4.20)");var global=this,process={env:{}},setTimeout=global.setTimeout;!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define(t):t()}(0,function(){"use strict";var t,c,r,l;function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function n(e,t){return e(t={exports:{}},t.exports),t.exports}Array.from||(Array.from=(t=Object.prototype.toString,c=function(e){return"function"==typeof e||"[object Function]"===t.call(e)},r=Math.pow(2,53)-1,l=function(e){var t,n=(t=Number(e),isNaN(t)?0:0!==t&&isFinite(t)?(0<t?1:-1)*Math.floor(Math.abs(t)):t);return Math.min(Math.max(n,0),r)},function(e){var t=Object(e);if(null==e)throw new TypeError("Array.from requires an array-like object - not null or undefined");var n,r=1<arguments.length?arguments[1]:void 0;if(void 0!==r){if(!c(r))throw new TypeError("Array.from: when provided, the second argument must be a function");2<arguments.length&&(n=arguments[2])}for(var o,i=l(t.length),a=c(this)?Object(new this(i)):new Array(i),s=0;s<i;)o=t[s],a[s]=r?void 0===n?r(o,s):r.call(n,o,s):o,s+=1;return a.length=i,a}));var v=n(function(e){var t=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)}),m=n(function(e){var t=e.exports={version:"2.5.7"};"number"==typeof __e&&(__e=t)}),o=(m.version,function(e){return"object"==typeof e?null!==e:"function"==typeof e}),y=function(e){if(!o(e))throw TypeError(e+" is not an object!");return e},i=function(e){try{return!!e()}catch(e){return!0}},a=!i(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}),s=v.document,u=o(s)&&o(s.createElement),f=function(e){return u?s.createElement(e):{}},p=!a&&!i(function(){return 7!=Object.defineProperty(f("div"),"a",{get:function(){return 7}}).a}),d=Object.defineProperty,h={f:a?Object.defineProperty:function(e,t,n){if(y(e),t=function(e,t){if(!o(e))return e;var n,r;if(t&&"function"==typeof(n=e.toString)&&!o(r=n.call(e)))return r;if("function"==typeof(n=e.valueOf)&&!o(r=n.call(e)))return r;if(!t&&"function"==typeof(n=e.toString)&&!o(r=n.call(e)))return r;throw TypeError("Can't convert object to primitive value")}(t,!0),y(n),p)try{return d(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(e[t]=n.value),e}},k=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}},S=a?function(e,t,n){return h.f(e,t,k(1,n))}:function(e,t,n){return e[t]=n,e},g={}.hasOwnProperty,_=function(e,t){return g.call(e,t)},b=0,w=Math.random(),O=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++b+w).toString(36))},C=n(function(e){var i=O("src"),t="toString",n=Function[t],a=(""+n).split(t);m.inspectSource=function(e){return n.call(e)},(e.exports=function(e,t,n,r){var o="function"==typeof n;o&&(_(n,"name")||S(n,"name",t)),e[t]!==n&&(o&&(_(n,i)||S(n,i,e[t]?""+e[t]:a.join(String(t)))),e===v?e[t]=n:r?e[t]?e[t]=n:S(e,t,n):(delete e[t],S(e,t,n)))})(Function.prototype,t,function(){return"function"==typeof this&&this[i]||n.call(this)})}),x=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e},E=function(r,o,e){if(x(r),void 0===o)return r;switch(e){case 1:return function(e){return r.call(o,e)};case 2:return function(e,t){return r.call(o,e,t)};case 3:return function(e,t,n){return r.call(o,e,t,n)}}return function(){return r.apply(o,arguments)}},$="prototype",A=function(e,t,n){var r,o,i,a,s=e&A.F,c=e&A.G,l=e&A.S,u=e&A.P,f=e&A.B,p=c?v:l?v[t]||(v[t]={}):(v[t]||{})[$],d=c?m:m[t]||(m[t]={}),h=d[$]||(d[$]={});for(r in c&&(n=t),n)i=((o=!s&&p&&void 0!==p[r])?p:n)[r],a=f&&o?E(i,v):u&&"function"==typeof i?E(Function.call,i):i,p&&C(p,r,i,e&A.U),d[r]!=i&&S(d,r,a),u&&h[r]!=i&&(h[r]=i)};v.core=m,A.F=1,A.G=2,A.S=4,A.P=8,A.B=16,A.W=32,A.U=64,A.R=128;var I,j=A,M={}.toString,T=function(e){return M.call(e).slice(8,-1)},P=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==T(e)?e.split(""):Object(e)},F=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e},N=function(e){return P(F(e))},R=Math.ceil,D=Math.floor,V=function(e){return isNaN(e=+e)?0:(0<e?D:R)(e)},L=Math.min,J=function(e){return 0<e?L(V(e),9007199254740991):0},W=Math.max,q=Math.min,B=n(function(e){var t="__core-js_shared__",n=v[t]||(v[t]={});(e.exports=function(e,t){return n[e]||(n[e]=void 0!==t?t:{})})("versions",[]).push({version:m.version,mode:"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})}),U=B("keys"),z=function(e){return U[e]||(U[e]=O(e))},H=(I=!1,function(e,t,n){var r,o,i,a=N(e),s=J(a.length),c=(o=s,(r=V(r=n))<0?W(r+o,0):q(r,o));if(I&&t!=t){for(;c<s;)if((i=a[c++])!=i)return!0}else for(;c<s;c++)if((I||c in a)&&a[c]===t)return I||c||0;return!I&&-1}),G=z("IE_PROTO"),X="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","),K=Object.keys||function(e){return function(e,t){var n,r=N(e),o=0,i=[];for(n in r)n!=G&&_(r,n)&&i.push(n);for(;t.length>o;)_(r,n=t[o++])&&(~H(i,n)||i.push(n));return i}(e,X)},Z={f:Object.getOwnPropertySymbols},Y={f:{}.propertyIsEnumerable},Q=function(e){return Object(F(e))},ee=Object.assign,te=!ee||i(function(){var e={},t={},n=Symbol(),r="abcdefghijklmnopqrst";return e[n]=7,r.split("").forEach(function(e){t[e]=e}),7!=ee({},e)[n]||Object.keys(ee({},t)).join("")!=r})?function(e,t){for(var n=arguments,r=Q(e),o=arguments.length,i=1,a=Z.f,s=Y.f;i<o;)for(var c,l=P(n[i++]),u=a?K(l).concat(a(l)):K(l),f=u.length,p=0;p<f;)s.call(l,c=u[p++])&&(r[c]=l[c]);return r}:ee;j(j.S+j.F,"Object",{assign:te});m.Object.assign;Object.setPrototypeOf||(Object.setPrototypeOf=function(t,n){var r;function o(e,t){return r.call(e,t),e}try{(r=t.getOwnPropertyDescriptor(t.prototype,n).set).call({},null)}catch(e){if(t.prototype!=={}[n])return;r=function(e){this[n]=e},o.polyfill=o(o({},null),t.prototype)instanceof t}return o}(Object,"__proto__"));var ne=global.WXEnvironment;void 0===ne||"iOS"!==ne.platform||ne.__enable_native_promise__||(global.Promise=void 0);var re=n(function(e){var t=B("wks"),n=v.Symbol,r="function"==typeof n;(e.exports=function(e){return t[e]||(t[e]=r&&n[e]||(r?n:O)("Symbol."+e))}).store=t}),oe=re("toStringTag"),ie="Arguments"==T(function(){return arguments}()),ae=function(e){var t,n,r;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(n=function(e,t){try{return e[t]}catch(e){}}(t=Object(e),oe))?n:ie?T(t):"Object"==(r=T(t))&&"function"==typeof t.callee?"Arguments":r},se={};se[re("toStringTag")]="z",se+""!="[object z]"&&C(Object.prototype,"toString",function(){return"[object "+ae(this)+"]"},!0);var ce={},le=a?Object.defineProperties:function(e,t){y(e);for(var n,r=K(t),o=r.length,i=0;i<o;)h.f(e,n=r[i++],t[n]);return e},ue=v.document,fe=ue&&ue.documentElement,pe=z("IE_PROTO"),de=function(){},he="prototype",ve=function(){var e,t=f("iframe"),n=X.length;for(t.style.display="none",fe.appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write("<script>document.F=Object<\/script>"),e.close(),ve=e.F;n--;)delete ve[he][X[n]];return ve()},me=Object.create||function(e,t){var n;return null!==e?(de[he]=y(e),n=new de,de[he]=null,n[pe]=e):n=ve(),void 0===t?n:le(n,t)},ye=h.f,ge=re("toStringTag"),_e=function(e,t,n){e&&!_(e=n?e:e.prototype,ge)&&ye(e,ge,{configurable:!0,value:t})},be={};S(be,re("iterator"),function(){return this});var we,ke=z("IE_PROTO"),Se=Object.prototype,Oe=Object.getPrototypeOf||function(e){return e=Q(e),_(e,ke)?e[ke]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?Se:null},Ce=re("iterator"),xe=!([].keys&&"next"in[].keys()),Ee="values",$e=function(){return this},Ae=function(e,t,n,r,o,i,a){var s,c,l;c=t,l=r,(s=n).prototype=me(be,{next:k(1,l)}),_e(s,c+" Iterator");var u,f,p,d=function(e){if(!xe&&e in y)return y[e];switch(e){case"keys":case Ee:return function(){return new n(this,e)}}return function(){return new n(this,e)}},h=t+" Iterator",v=o==Ee,m=!1,y=e.prototype,g=y[Ce]||y["@@iterator"]||o&&y[o],_=g||d(o),b=o?v?d("entries"):_:void 0,w="Array"==t&&y.entries||g;if(w&&(p=Oe(w.call(new e)))!==Object.prototype&&p.next&&(_e(p,h,!0),"function"!=typeof p[Ce]&&S(p,Ce,$e)),v&&g&&g.name!==Ee&&(m=!0,_=function(){return g.call(this)}),(xe||m||!y[Ce])&&S(y,Ce,_),ce[t]=_,ce[h]=$e,o)if(u={values:v?_:d(Ee),keys:i?_:d("keys"),entries:b},a)for(f in u)f in y||C(y,f,u[f]);else j(j.P+j.F*(xe||m),t,u);return u},Ie=(we=!0,function(e,t){var n,r,o=String(F(e)),i=V(t),a=o.length;return i<0||a<=i?we?"":void 0:(n=o.charCodeAt(i))<55296||56319<n||i+1===a||(r=o.charCodeAt(i+1))<56320||57343<r?we?o.charAt(i):n:we?o.slice(i,i+2):r-56320+(n-55296<<10)+65536});Ae(String,"String",function(e){this._t=String(e),this._i=0},function(){var e,t=this._t,n=this._i;return n>=t.length?{value:void 0,done:!0}:(e=Ie(t,n),this._i+=e.length,{value:e,done:!1})});var je=re("unscopables"),Me=Array.prototype;null==Me[je]&&S(Me,je,{});var Te=function(e){Me[je][e]=!0},Pe=function(e,t){return{value:t,done:!!e}},Fe=Ae(Array,"Array",function(e,t){this._t=N(e),this._i=0,this._k=t},function(){var e=this._t,t=this._k,n=this._i++;return!e||n>=e.length?(this._t=void 0,Pe(1)):Pe(0,"keys"==t?n:"values"==t?e[n]:[n,e[n]])},"values");ce.Arguments=ce.Array,Te("keys"),Te("values"),Te("entries");for(var Ne=re("iterator"),Re=re("toStringTag"),De=ce.Array,Ve={CSSRuleList:!0,CSSStyleDeclaration:!1,CSSValueList:!1,ClientRectList:!1,DOMRectList:!1,DOMStringList:!1,DOMTokenList:!0,DataTransferItemList:!1,FileList:!1,HTMLAllCollection:!1,HTMLCollection:!1,HTMLFormElement:!1,HTMLSelectElement:!1,MediaList:!0,MimeTypeArray:!1,NamedNodeMap:!1,NodeList:!0,PaintRequestList:!1,Plugin:!1,PluginArray:!1,SVGLengthList:!1,SVGNumberList:!1,SVGPathSegList:!1,SVGPointList:!1,SVGStringList:!1,SVGTransformList:!1,SourceBufferList:!1,StyleSheetList:!0,TextTrackCueList:!1,TextTrackList:!1,TouchList:!1},Le=K(Ve),Je=0;Je<Le.length;Je++){var We,qe=Le[Je],Be=Ve[qe],Ue=v[qe],ze=Ue&&Ue.prototype;if(ze&&(ze[Ne]||S(ze,Ne,De),ze[Re]||S(ze,Re,qe),ce[qe]=De,Be))for(We in Fe)ze[We]||C(ze,We,Fe[We],!0)}var He,Ge,Xe,Ke=function(t,e,n,r){try{return r?e(y(n)[0],n[1]):e(n)}catch(e){var o=t.return;throw void 0!==o&&y(o.call(t)),e}},Ze=re("iterator"),Ye=Array.prototype,Qe=re("iterator"),et=m.getIteratorMethod=function(e){if(null!=e)return e[Qe]||e["@@iterator"]||ce[ae(e)]},tt=n(function(e){var d={},h={},t=e.exports=function(e,t,n,r,o){var i,a,s,c,l,u=o?function(){return e}:et(e),f=E(n,r,t?2:1),p=0;if("function"!=typeof u)throw TypeError(e+" is not iterable!");if(void 0===(l=u)||ce.Array!==l&&Ye[Ze]!==l){for(s=u.call(e);!(a=s.next()).done;)if((c=Ke(s,f,a.value,t))===d||c===h)return c}else for(i=J(e.length);p<i;p++)if((c=t?f(y(a=e[p])[0],a[1]):f(e[p]))===d||c===h)return c};t.BREAK=d,t.RETURN=h}),nt=re("species"),rt=v.process,ot=v.setImmediate,it=v.clearImmediate,at=v.MessageChannel,st=v.Dispatch,ct=0,lt={},ut="onreadystatechange",ft=function(){var e=+this;if(lt.hasOwnProperty(e)){var t=lt[e];delete lt[e],t()}},pt=function(e){ft.call(e.data)};ot&&it||(ot=function(e){for(var t=arguments,n=[],r=1;arguments.length>r;)n.push(t[r++]);return lt[++ct]=function(){!function(e,t,n){var r=void 0===n;switch(t.length){case 0:return r?e():e.call(n);case 1:return r?e(t[0]):e.call(n,t[0]);case 2:return r?e(t[0],t[1]):e.call(n,t[0],t[1]);case 3:return r?e(t[0],t[1],t[2]):e.call(n,t[0],t[1],t[2]);case 4:return r?e(t[0],t[1],t[2],t[3]):e.call(n,t[0],t[1],t[2],t[3])}e.apply(n,t)}("function"==typeof e?e:Function(e),n)},He(ct),ct},it=function(e){delete lt[e]},"process"==T(rt)?He=function(e){rt.nextTick(E(ft,e,1))}:st&&st.now?He=function(e){st.now(E(ft,e,1))}:at?(Xe=(Ge=new at).port2,Ge.port1.onmessage=pt,He=E(Xe.postMessage,Xe,1)):v.addEventListener&&"function"==typeof postMessage&&!v.importScripts?(He=function(e){v.postMessage(e+"","*")},v.addEventListener("message",pt,!1)):He=ut in f("script")?function(e){fe.appendChild(f("script"))[ut]=function(){fe.removeChild(this),ft.call(e)}}:function(e){setTimeout(E(ft,e,1),0)});var dt={set:ot,clear:it},ht=dt.set,vt=v.MutationObserver||v.WebKitMutationObserver,mt=v.process,yt=v.Promise,gt="process"==T(mt);function _t(e){var n,r;this.promise=new e(function(e,t){if(void 0!==n||void 0!==r)throw TypeError("Bad Promise constructor");n=e,r=t}),this.resolve=x(n),this.reject=x(r)}var bt={f:function(e){return new _t(e)}},wt=function(e){try{return{e:!1,v:e()}}catch(e){return{e:!0,v:e}}},kt=v.navigator,St=kt&&kt.userAgent||"",Ot=re("species"),Ct=re("iterator"),xt=!1;try{[7][Ct]().return=function(){xt=!0}}catch(e){}var Et,$t,At,It,jt,Mt=dt.set,Tt=function(){var n,r,o,e=function(){var e,t;for(gt&&(e=mt.domain)&&e.exit();n;){t=n.fn,n=n.next;try{t()}catch(e){throw n?o():r=void 0,e}}r=void 0,e&&e.enter()};if(gt)o=function(){mt.nextTick(e)};else if(!vt||v.navigator&&v.navigator.standalone)if(yt&&yt.resolve){var t=yt.resolve(void 0);o=function(){t.then(e)}}else o=function(){ht.call(v,e)};else{var i=!0,a=document.createTextNode("");new vt(e).observe(a,{characterData:!0}),o=function(){a.data=i=!i}}return function(e){var t={fn:e,next:void 0};r&&(r.next=t),n||(n=t,o()),r=t}}(),Pt="Promise",Ft=v.TypeError,Nt=v.process,Rt=Nt&&Nt.versions,Dt=Rt&&Rt.v8||"",Vt=v[Pt],Lt="process"==ae(Nt),Jt=function(){},Wt=$t=bt.f,qt=!!function(){try{var e=Vt.resolve(1),t=(e.constructor={})[re("species")]=function(e){e(Jt,Jt)};return(Lt||"function"==typeof PromiseRejectionEvent)&&e.then(Jt)instanceof t&&0!==Dt.indexOf("6.6")&&-1===St.indexOf("Chrome/66")}catch(e){}}(),Bt=function(e){var t;return!(!o(e)||"function"!=typeof(t=e.then))&&t},Ut=function(u,n){if(!u._n){u._n=!0;var r=u._c;Tt(function(){for(var c=u._v,l=1==u._s,e=0,t=function(e){var t,n,r,o=l?e.ok:e.fail,i=e.resolve,a=e.reject,s=e.domain;try{o?(l||(2==u._h&&Gt(u),u._h=1),!0===o?t=c:(s&&s.enter(),t=o(c),s&&(s.exit(),r=!0)),t===e.promise?a(Ft("Promise-chain cycle")):(n=Bt(t))?n.call(t,i,a):i(t)):a(c)}catch(e){s&&!r&&s.exit(),a(e)}};r.length>e;)t(r[e++]);u._c=[],u._n=!1,n&&!u._h&&zt(u)})}},zt=function(i){Mt.call(v,function(){var e,t,n,r=i._v,o=Ht(i);if(o&&(e=wt(function(){Lt?Nt.emit("unhandledRejection",r,i):(t=v.onunhandledrejection)?t({promise:i,reason:r}):(n=v.console)&&n.error&&n.error("Unhandled promise rejection",r)}),i._h=Lt||Ht(i)?2:1),i._a=void 0,o&&e.e)throw e.v})},Ht=function(e){return 1!==e._h&&0===(e._a||e._c).length},Gt=function(t){Mt.call(v,function(){var e;Lt?Nt.emit("rejectionHandled",t):(e=v.onrejectionhandled)&&e({promise:t,reason:t._v})})},Xt=function(e){var t=this;t._d||(t._d=!0,(t=t._w||t)._v=e,t._s=2,t._a||(t._a=t._c.slice()),Ut(t,!0))},Kt=function(e){var n,r=this;if(!r._d){r._d=!0,r=r._w||r;try{if(r===e)throw Ft("Promise can't be resolved itself");(n=Bt(e))?Tt(function(){var t={_w:r,_d:!1};try{n.call(e,E(Kt,t,1),E(Xt,t,1))}catch(e){Xt.call(t,e)}}):(r._v=e,r._s=1,Ut(r,!1))}catch(e){Xt.call({_w:r,_d:!1},e)}}};qt||(Vt=function(e){!function(e,t,n,r){if(!(e instanceof t)||void 0!==r&&r in e)throw TypeError(n+": incorrect invocation!")}(this,Vt,Pt,"_h"),x(e),Et.call(this);try{e(E(Kt,this,1),E(Xt,this,1))}catch(e){Xt.call(this,e)}},(Et=function(e){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1}).prototype=function(e,t,n){for(var r in t)C(e,r,t[r],n);return e}(Vt.prototype,{then:function(e,t){var n,r,o,i=Wt((n=Vt,void 0===(o=y(this).constructor)||null==(r=y(o)[nt])?n:x(r)));return i.ok="function"!=typeof e||e,i.fail="function"==typeof t&&t,i.domain=Lt?Nt.domain:void 0,this._c.push(i),this._a&&this._a.push(i),this._s&&Ut(this,!1),i.promise},catch:function(e){return this.then(void 0,e)}}),At=function(){var e=new Et;this.promise=e,this.resolve=E(Kt,e,1),this.reject=E(Xt,e,1)},bt.f=Wt=function(e){return e===Vt||e===It?new At(e):$t(e)}),j(j.G+j.W+j.F*!qt,{Promise:Vt}),_e(Vt,Pt),jt=v[Pt],a&&jt&&!jt[Ot]&&h.f(jt,Ot,{configurable:!0,get:function(){return this}}),It=m[Pt],j(j.S+j.F*!qt,Pt,{reject:function(e){var t=Wt(this);return(0,t.reject)(e),t.promise}}),j(j.S+j.F*!qt,Pt,{resolve:function(e){return function(e,t){if(y(e),o(t)&&t.constructor===e)return t;var n=bt.f(e);return(0,n.resolve)(t),n.promise}(this,e)}}),j(j.S+j.F*!(qt&&function(e,t){if(!t&&!xt)return!1;var n=!1;try{var r=[7],o=r[Ct]();o.next=function(){return{done:n=!0}},r[Ct]=function(){return o},e(r)}catch(e){}return n}(function(e){Vt.all(e).catch(Jt)})),Pt,{all:function(e){var a=this,t=Wt(a),s=t.resolve,c=t.reject,n=wt(function(){var r=[],o=0,i=1;tt(e,!1,function(e){var t=o++,n=!1;r.push(void 0),i++,a.resolve(e).then(function(e){n||(n=!0,r[t]=e,--i||s(r))},c)}),--i||s(r)});return n.e&&c(n.v),t.promise},race:function(e){var t=this,n=Wt(t),r=n.reject,o=wt(function(){tt(e,!1,function(e){t.resolve(e).then(n.resolve,r)})});return o.e&&r(o.v),n.promise}});var Zt=1;function Yt(){return(Zt++).toString()}function Qt(e){var t=Object.prototype.toString.call(e);return t.substring(8,t.length-1)}function en(e){if("function"!=typeof btoa)return"";var t=Array.prototype.map.call(new Uint8Array(e),function(e){return String.fromCharCode(e)}).join("");return btoa(t)}function tn(e){if(!e||"object"!=typeof e)return!0;for(var t in e)if(Object.prototype.hasOwnProperty.call(e,t))return!1;return!0}var nn=["off","error","warn","info","log","debug"],rn={};function on(e){var t=global.WXEnvironment&&global.WXEnvironment.logLevel||"log";return rn[t]&&rn[t][e]}function an(e){global.nativeLog("wxInteractionAnalyzer: [jsfm]"+e,"__DEBUG")}global.console;function sn(e){return e.map(function(e){return e="[object object]"===Object.prototype.toString.call(e).toLowerCase()?JSON.stringify(e):String(e)})}global.setTimeout;var cn=global.setTimeoutNative;function ln(t,n,r){if(t.hasOwnProperty(n)){var e=t[n];Object.defineProperty(t,n,{get:function(){return e},set:function(e){if(this===t)throw Error("Cannot assign to read only property "+n+" of "+r);return Object.defineProperty(this,n,{value:e,writable:!0}),e}})}}!function(){if(void 0===setTimeout&&"function"==typeof cn){var n={},r=0;global.setTimeout=function(e,t){n[++r]=e,cn(r.toString(),t)},global.setTimeoutCallback=function(e){"function"==typeof n[e]&&(n[e](),delete n[e])}}}(),"undefined"==typeof WXEnvironment||WXEnvironment.__enable_native_promise__,function(){if(nn.forEach(function(t){var n=nn.indexOf(t);rn[t]={},nn.forEach(function(e){nn.indexOf(e)<=n&&(rn[t][e]=!0)})}),global.WXEnvironment&&"Web"!==global.WXEnvironment.platform)global.console={debug:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];on("debug")&&global.nativeLog.apply(global,sn(e).concat(["__DEBUG"]))},log:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];on("log")&&global.nativeLog.apply(global,sn(e).concat(["__LOG"]))},info:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];on("info")&&global.nativeLog.apply(global,sn(e).concat(["__INFO"]))},warn:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];on("warn")&&global.nativeLog.apply(global,sn(e).concat(["__WARN"]))},error:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];on("error")&&global.nativeLog.apply(global,sn(e).concat(["__ERROR"]))}};else{var e=console.debug,t=console.log,n=console.info,r=console.warn,o=console.error;console.__ori__={debug:e,log:t,info:n,warn:r,error:o},console.debug=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];on("debug")&&console.__ori__.debug.apply(console,e)},console.log=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];on("log")&&console.__ori__.log.apply(console,e)},console.info=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];on("info")&&console.__ori__.info.apply(console,e)},console.warn=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];on("warn")&&console.__ori__.warn.apply(console,e)},console.error=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];on("error")&&console.__ori__.error.apply(console,e)}}}();var un={framework:"0.29.1",transformer:">=0.1.5 <0.5"};function fn(e,t,n){return t+"@"+n+"#"+e}var pn=function(e){this.instanceId=String(e),this.lastCallbackId=0,this.callbacks={},this.hooks={}};pn.prototype.add=function(e){return this.lastCallbackId++,this.callbacks[this.lastCallbackId]=e,this.lastCallbackId},pn.prototype.remove=function(e){var t=this.callbacks[e];return delete this.callbacks[e],t},pn.prototype.registerHook=function(e,t,n,r){var o=fn(e,t,n);this.hooks[o]&&console.warn('[JS Framework] Override an existing component hook "'+o+'".'),this.hooks[o]=r},pn.prototype.triggerHook=function(e,t,n,r){var o=fn(e,t,n),i=this.hooks[o];if("function"!=typeof i)return console.error("[JS Framework] Invalid hook function type ("+typeof i+') on "'+o+'".'),null;var a=null;try{a=i.apply(null,r||[])}catch(e){throw console.error('[JS Framework] Failed to execute the hook function on "'+o+'".'),e}return a},pn.prototype.consume=function(e,t,n){var r=this.callbacks[e];if(void 0!==n&&!1!==n||delete this.callbacks[e],"function"==typeof r)try{return r.call(null,t)}catch(e){throw console.error("[JS Framework] Failed to execute the callback function:\n "+e.toString()),e}return new Error('invalid callback id "'+e+'"')},pn.prototype.close=function(){this.callbacks={},this.hooks={}};var dn={};function hn(e){return dn[e]}function vn(e){var t=dn[e];return t&&t.taskCenter?t.taskCenter:null}function mn(e,t,n){var r=e.documentElement;if(!(0<r.pureChildren.length||t.parentNode)){var o,i,a=r.children,s=a.indexOf(n);s<0?a.push(t):a.splice(s,0,t),1===t.nodeType?("body"===t.role?(t.docId=e.id,t.ownerDocument=e,t.parentNode=r,gn(t,r)):(t.children.forEach(function(e){e.parentNode=t}),yn(e,t),t.docId=e.id,t.ownerDocument=e,gn(t,r),delete e.nodeMap[t.nodeId]),r.pureChildren.push(t),o=e,i=t.toJSON(),o&&o.taskCenter&&"function"==typeof o.taskCenter.send&&o.taskCenter.send("dom",{action:"createBody"},[i])):(t.parentNode=r,e.nodeMap[t.ref]=t)}}function yn(e,t){t.role="body",t.depth=1,delete e.nodeMap[t.nodeId],t.ref="_root",e.nodeMap._root=t,e.body=t}function gn(t,e){(t.parentNode=e).docId&&(t.docId=e.docId,t.ownerDocument=e.ownerDocument,(t.ownerDocument.nodeMap[t.nodeId]=t).depth=e.depth+1),t.children.forEach(function(e){gn(e,t)})}function _n(e){for(;e;){if(1===e.nodeType)return e;e=e.nextSibling}}function bn(e){for(;e;){if(1===e.nodeType)return e;e=e.previousSibling}}function wn(e,t,n,r){n<0&&(n=0);var o=t[n-1],i=t[n];return t.splice(n,0,e),r&&(o&&(o.nextSibling=e),e.previousSibling=o,(e.nextSibling=i)&&(i.previousSibling=e)),n}function kn(e,t,n,r){var o=t.indexOf(e);if(o<0)return-1;if(r){var i=t[o-1],a=t[o+1];i&&(i.nextSibling=a),a&&(a.previousSibling=i)}t.splice(o,1);var s=n;o<=n&&(s=n-1);var c=t[s-1],l=t[s];return t.splice(s,0,e),r&&(c&&(c.nextSibling=e),e.previousSibling=c,(e.nextSibling=l)&&(l.previousSibling=e)),o===s?-1:n}function Sn(e,t,n){var r=t.indexOf(e);if(!(r<0)){if(n){var o=t[r-1],i=t[r+1];o&&(o.nextSibling=i),i&&(i.previousSibling=o)}t.splice(r,1)}}var On,Cn=function(){this.nodeId=Yt(),this.ref=this.nodeId,this.children=[],this.pureChildren=[],this.parentNode=null,this.nextSibling=null,this.previousSibling=null};Cn.prototype.destroy=function(){var e=hn(this.docId);e&&(delete this.docId,delete e.nodeMap[this.nodeId]),this.children.forEach(function(e){e.destroy()})};var xn={};var En=["click","longpress","touchstart","touchmove","touchend","panstart","panmove","panend","horizontalpan","verticalpan","swipe"];function $n(e,t){hn(e).nodeMap[t.nodeId]=t}var An=function(o){function e(e,t,n){void 0===e&&(e="div"),o.call(this);var r=xn[e];if(r&&!n)return new r(e,t,!0);t=t||{},this.nodeType=1,this.nodeId=Yt(),this.ref=this.nodeId,this.type=e,this.attr=t.attr||{},this.style=t.style||{},this.classStyle=t.classStyle||{},this.event={},this.children=[],this.pureChildren=[]}return o&&(e.__proto__=o),((e.prototype=Object.create(o&&o.prototype)).constructor=e).prototype.appendChild=function(e){if(!e.parentNode||e.parentNode===this)if(e.parentNode){if(on("debug")&&an("[appendChild]("+this.docId+","+e.type+","+e.ref+") Move <"+e.type+"> to "+this.children.length+" of <"+this.type+"> ("+this.ref+")."),kn(e,this.children,this.children.length,!0),1===e.nodeType){var t=kn(e,this.pureChildren,this.pureChildren.length),n=vn(this.docId);if(n&&0<=t)return n.send("dom",{action:"moveElement"},[e.ref,this.ref,t])}}else if(on("debug")&&an("[appendChild]("+this.docId+","+e.type+","+e.ref+") Append <"+e.type+"> to <"+this.type+"> ("+this.ref+")."),gn(e,this),wn(e,this.children,this.children.length,!0),this.docId&&$n(this.docId,e),1===e.nodeType){wn(e,this.pureChildren,this.pureChildren.length);var r=vn(this.docId);if(r)return r.send("dom",{action:"addElement"},[this.ref,e.toJSON(),-1])}},e.prototype.insertBefore=function(e,t){if(!(e.parentNode&&e.parentNode!==this||e===t||e.nextSibling&&e.nextSibling===t))if(e.parentNode){if(kn(e,this.children,this.children.indexOf(t),!0),1===e.nodeType){var n=_n(t),r=kn(e,this.pureChildren,n?this.pureChildren.indexOf(n):this.pureChildren.length),o=vn(this.docId);if(o&&0<=r)return o.send("dom",{action:"moveElement"},[e.ref,this.ref,r])}}else if(on("debug")&&an("[insertBefore]("+this.docId+","+e.type+","+e.ref+") Insert <"+e.type+"> to <"+this.type+"> ("+this.ref+"), before ("+t.ref+")."),gn(e,this),wn(e,this.children,this.children.indexOf(t),!0),this.docId&&$n(this.docId,e),1===e.nodeType){var i=_n(t),a=wn(e,this.pureChildren,i?this.pureChildren.indexOf(i):this.pureChildren.length),s=vn(this.docId);if(s)return s.send("dom",{action:"addElement"},[this.ref,e.toJSON(),a])}},e.prototype.insertAfter=function(e,t){if(!(e.parentNode&&e.parentNode!==this||e===t||e.previousSibling&&e.previousSibling===t))if(e.parentNode){if(kn(e,this.children,this.children.indexOf(t)+1,!0),1===e.nodeType){var n=kn(e,this.pureChildren,this.pureChildren.indexOf(bn(t))+1),r=vn(this.docId);if(r&&0<=n)return r.send("dom",{action:"moveElement"},[e.ref,this.ref,n])}}else if(on("debug")&&an("[insertAfter]("+this.docId+","+e.type+","+e.ref+") Insert <"+e.type+"> to <"+this.type+"> ("+this.ref+"), after ("+t.ref+")."),gn(e,this),wn(e,this.children,this.children.indexOf(t)+1,!0),this.docId&&$n(this.docId,e),1===e.nodeType){var o=wn(e,this.pureChildren,this.pureChildren.indexOf(bn(t))+1),i=vn(this.docId);if(i)return i.send("dom",{action:"addElement"},[this.ref,e.toJSON(),o])}},e.prototype.removeChild=function(e,t){if(e.parentNode&&(Sn(e,this.children,!0),1===e.nodeType)){on("debug")&&an("[removeChild]("+this.docId+","+e.type+","+e.ref+") Remove <"+e.type+"> from <"+this.type+"> ("+this.ref+")."),Sn(e,this.pureChildren);var n=vn(this.docId);n&&n.send("dom",{action:"removeElement"},[e.ref])}t||e.destroy()},e.prototype.clear=function(){var t=vn(this.docId);t&&this.pureChildren.forEach(function(e){t.send("dom",{action:"removeElement"},[e.ref])}),this.children.forEach(function(e){e.destroy()}),this.children.length=0,this.pureChildren.length=0},e.prototype.setAttr=function(e,t,n){if(this.attr[e]!==t||!1===n){this.attr[e]=t;var r=vn(this.docId);if(!n&&r){var o={};o[e]=t,r.send("dom",{action:"updateAttrs"},[this.ref,o])}}},e.prototype.setAttrs=function(e,t){if(!tn(e)){var n={};for(var r in e)this.attr[r]!==e[r]&&(this.attr[r]=e[r],n[r]=e[r]);if(!tn(n)){var o=vn(this.docId);!t&&o&&o.send("dom",{action:"updateAttrs"},[this.ref,n])}}},e.prototype.setStyle=function(e,t,n){if(this.style[e]!==t||!1===n){this.style[e]=t;var r=vn(this.docId);if(!n&&r){var o={};o[e]=t,r.send("dom",{action:"updateStyle"},[this.ref,o])}}},e.prototype.setStyles=function(e,t){if(!tn(e)){var n={};for(var r in e)this.style[r]!==e[r]&&(this.style[r]=e[r],n[r]=e[r]);if(!tn(n)){var o=vn(this.docId);!t&&o&&o.send("dom",{action:"updateStyle"},[this.ref,n])}}},e.prototype.setClassStyle=function(e){for(var t in this.classStyle)this.classStyle[t]="";Object.assign(this.classStyle,e);var n=vn(this.docId);n&&n.send("dom",{action:"updateStyle"},[this.ref,this.toStyle()])},e.prototype.addEvent=function(e,t,n){if(this.event||(this.event={}),!this.event[e]){on("debug")&&an("[addEvent]("+this.docId+","+this.type+","+this.ref+') Add "'+e+'" event on <'+this.type+"> ("+this.ref+")."),this.event[e]={handler:t,params:n};var r=vn(this.docId);r&&r.send("dom",{action:"addEvent"},[this.ref,e])}},e.prototype.removeEvent=function(e){if(this.event&&this.event[e]){on("debug")&&an("[removeEvent]("+this.docId+","+this.type+","+this.ref+') Remove "'+e+'" event on <'+this.type+"> ("+this.ref+")."),delete this.event[e];var t=vn(this.docId);t&&t.send("dom",{action:"removeEvent"},[this.ref,e])}},e.prototype.fireEvent=function(t,e,n,r){var o=null,i=!1,a=this.event[t];if(a&&e){on("debug")&&an("[fireEvent]("+this.docId+","+this.type+","+this.ref+') Fire "'+t+'" event on <'+this.type+"> ("+this.ref+").");var s=a.handler;e.stopPropagation=function(){i=!0};try{o=r&&r.params?s.call.apply(s,[this].concat(r.params,[e])):s.call(this,e)}catch(e){throw console.error('[JS Framework] Failed to invoke the event handler of "'+t+'" on '+this.type+" ("+this.ref+"):\n "+e.toString()),e}}return!i&&n&&-1!==En.indexOf(t)&&this.parentNode&&this.parentNode.fireEvent&&(e.currentTarget=this.parentNode,this.parentNode.fireEvent(t,e,n)),o},e.prototype.toStyle=function(){return Object.assign({},this.classStyle,this.style)},e.prototype.toJSON=function(e){void 0===e&&(e=!1);var t={ref:this.ref.toString(),type:this.type,attr:this.attr,style:this.toStyle()},n=[];for(var r in this.event){var o=this.event[r].params;o?n.push({type:r,params:o}):n.push(r)}return n.length&&(t.event=n),!e&&this.pureChildren.length&&(t.children=this.pureChildren.map(function(e){return e.toJSON()})),t},e.prototype.toString=function(){return"<"+this.type+" attr="+JSON.stringify(this.attr)+" style="+JSON.stringify(this.toStyle())+">"+this.pureChildren.map(function(e){return e.toString()}).join("")+"</"+this.type+">"},e}(Cn);On=An;var In=function(){},jn=function(e,t){Object.defineProperty(this,"instanceId",{enumerable:!0,value:String(e)}),Object.defineProperty(this,"callbackManager",{enumerable:!0,value:new pn(e)}),In=t||function(){}};function Mn(e,t){var n=hn(e);return n?Array.isArray(t)?t.map(function(e){switch(e.method){case"callback":return function(e,t,n,r){return e.taskCenter.callback(t,n,r)}.apply(void 0,[n].concat(e.args));case"fireEventSync":case"fireEvent":return function(e,t,n,r,o,i){var a=e.getRef(t);return a?e.fireEvent(a,n,r,o,i):(r._nodeId=t,e.fireEvent(e.getRef("_documentElement"),n,r,o,i))}.apply(void 0,[n].concat(e.args));case"componentHook":return function(e,t,n,r,o){if(!e||!e.taskCenter)return console.error('[JS Framework] Can\'t find "document" or "taskCenter".'),null;var i=null;try{i=e.taskCenter.triggerHook(t,n,r,o)}catch(e){console.error('[JS Framework] Failed to trigger the "'+n+"@"+r+'" hook on '+t+".")}return i}.apply(void 0,[n].concat(e.args))}}):void 0:new Error("[JS Framework] Failed to receiveTasks, instance ("+e+") is not available.")}jn.prototype.callback=function(e,t,n){return this.callbackManager.consume(e,t,n)},jn.prototype.registerHook=function(){for(var e,t=[],n=arguments.length;n--;)t[n]=arguments[n];return(e=this.callbackManager).registerHook.apply(e,t)},jn.prototype.triggerHook=function(){for(var e,t=[],n=arguments.length;n--;)t[n]=arguments[n];return(e=this.callbackManager).triggerHook.apply(e,t)},jn.prototype.updateData=function(e,t,n){this.send("module",{module:"dom",method:"updateComponentData"},[e,t,n])},jn.prototype.destroyCallback=function(){return this.callbackManager.close()},jn.prototype.normalize=function(e,t){var n=this;void 0===t&&(t=!1);var r=Qt(e);if(e&&e instanceof An)return e.ref;if(e&&e._isVue&&e.$el instanceof An)return e.$el.ref;if("Function"===r)return this.callbackManager.add(e).toString();if(t){if("Object"===r){var o={};for(var i in e)o[i]=n.normalize(e[i],!0);return o}if("Array"===r)return e.map(function(e){return n.normalize(e,!0)})}return e&&e.ref&&e["[[VirtualElement]]"]?e.ref:function(e){var t=Qt(e);switch(t){case"Undefined":case"Null":return"";case"RegExp":return e.toString();case"Date":return e.toISOString();case"Number":case"String":case"Boolean":case"Array":case"Object":return e;case"ArrayBuffer":return{"@type":"binary",dataType:t,base64:en(e)};case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":return{"@type":"binary",dataType:t,base64:en(e.buffer)};default:return JSON.stringify(e)}}(e)},jn.prototype.send=function(e,t,n,r){var o=this,i=t.action,a=t.component,s=t.ref,c=t.module,l=t.method;switch(n=n.map(function(e){return o.normalize(e)}),"Object"===Qt(r)&&(r=this.normalize(r,!0)),e){case"dom":return on("debug")&&an("[task]("+this.instanceId+","+this.type+","+i+") "+JSON.stringify(n)),this[i](this.instanceId,n);case"component":return this.componentHandler(this.instanceId,s,l,n,Object.assign({component:a},r));default:return on("debug")&&an("[task]("+this.instanceId+","+c+","+l+") "+JSON.stringify(n)),this.moduleHandler(this.instanceId,c,l,n,r)}},jn.prototype.callDOM=function(e,t){return this[e](this.instanceId,t)},jn.prototype.callComponent=function(e,t,n,r){return this.componentHandler(this.instanceId,e,t,n,r)},jn.prototype.callModule=function(e,t,n,r){return this.moduleHandler(this.instanceId,e,t,n,r)};var Tn={};function Pn(e){var t=function(t){Tn[t]||(Tn[t]={}),e[t].forEach(function(e){"string"==typeof e?Tn[t][e]=!0:Tn[t][e.name]=e.args})};for(var n in e)t(n)}function Fn(e,t){return"string"==typeof t?!(!Tn[e]||!Tn[e][t]):!!Tn[e]}var Nn={};function Rn(e){Array.isArray(e)&&e.forEach(function(e){e&&("string"==typeof e?Nn[e]=!0:"object"==typeof e&&"string"==typeof e.type&&function(o,e){if(e&&e.length){var t=function(e){function t(){e.apply(this,arguments)}return e&&(t.__proto__=e),(t.prototype=Object.create(e&&e.prototype)).constructor=t}(On);e.forEach(function(r){t.prototype[r]=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];var n=vn(this.docId);if(n)return n.send("component",{ref:this.ref,component:o,method:r},e)}}),xn[o]=t}}((Nn[e.type]=e).type,e.methods))})}function Dn(e){return!!Nn[e]}var Vn=[];function Ln(e,t){Wn(e)?console.warn('Service "'+e+'" has been registered already!'):(t=Object.assign({},t),Vn.push({name:e,options:t}))}function Jn(n){Vn.some(function(e,t){if(e.name===n)return Vn.splice(t,1),!0})}function Wn(e){return t=e,0<=Vn.map(function(e){return e.name}).indexOf(t);var t}var qn=function(t){function e(e){t.call(this),this.nodeType=8,this.nodeId=Yt(),this.ref=this.nodeId,this.type="comment",this.value=e,this.children=[],this.pureChildren=[]}return t&&(e.__proto__=t),((e.prototype=Object.create(t&&t.prototype)).constructor=e).prototype.toString=function(){return"\x3c!-- "+this.value+" --\x3e"},e}(Cn);function Bn(e,t){return void 0===t&&(t=[]),{module:"dom",method:e,args:t}}var Un=function(e,t){this.id=e,this.batched=!1,this.updates=[],"function"==typeof t?Object.defineProperty(this,"handler",{configurable:!0,enumerable:!0,writable:!0,value:t}):console.error("[JS Runtime] invalid parameter, handler must be a function")};Un.prototype.createFinish=function(e){return(0,this.handler)([Bn("createFinish")],e)},Un.prototype.updateFinish=function(e){return(0,this.handler)([Bn("updateFinish")],e)},Un.prototype.refreshFinish=function(e){return(0,this.handler)([Bn("refreshFinish")],e)},Un.prototype.createBody=function(e){var t=e.toJSON(),n=t.children;delete t.children;var r=[Bn("createBody",[t])];return n&&r.push.apply(r,n.map(function(e){return Bn("addElement",[t.ref,e,-1])})),this.addActions(r)},Un.prototype.addElement=function(e,t,n){return 0<=n||(n=-1),this.addActions(Bn("addElement",[t,e.toJSON(),n]))},Un.prototype.removeElement=function(e){if(Array.isArray(e)){var t=e.map(function(e){return Bn("removeElement",[e])});return this.addActions(t)}return this.addActions(Bn("removeElement",[e]))},Un.prototype.moveElement=function(e,t,n){return this.addActions(Bn("moveElement",[e,t,n]))},Un.prototype.setAttr=function(e,t,n){var r={};return r[t]=n,this.addActions(Bn("updateAttrs",[e,r]))},Un.prototype.setStyle=function(e,t,n){var r={};return r[t]=n,this.addActions(Bn("updateStyle",[e,r]))},Un.prototype.setStyles=function(e,t){return this.addActions(Bn("updateStyle",[e,t]))},Un.prototype.addEvent=function(e,t){return this.addActions(Bn("addEvent",[e,t]))},Un.prototype.removeEvent=function(e,t){return this.addActions(Bn("removeEvent",[e,t]))},Un.prototype.handler=function(e,t){return t&&t()},Un.prototype.addActions=function(e){var t=this.updates,n=this.handler;if(Array.isArray(e)||(e=[e]),!this.batched)return n(e);t.push.apply(t,e)};var zn={createBody:"callCreateBody",addElement:"callAddElement",removeElement:"callRemoveElement",moveElement:"callMoveElement",updateAttrs:"callUpdateAttrs",updateStyle:"callUpdateStyle",addEvent:"callAddEvent",removeEvent:"callRemoveEvent"};function Hn(e,t,n){var r,o=t.module,i=t.method,a=t.args;return r=i,"dom"===o&&zn[r]&&"function"==typeof global[zn[r]]?global[zn[i]].apply(global,[e].concat(a,["-1"])):n(e,[t],"-1")}var Gn=function e(t,n,r){var o,i;t=t?t.toString():"",this.id=t,this.URL=n,i=this,(o=t)&&(dn[o]=i),this.nodeMap={};var a,s,c=e.Listener||Un;this.listener=new c(t,r||(a=t,"function"!=typeof(s=e.handler||global.callNative)&&console.error("[JS Runtime] no default handler"),function(e){Array.isArray(e)||(e=[e]);for(var t=0;t<e.length;t++){var n=Hn(a,e[t],s);if(-1===n)return n}})),this.taskCenter=new jn(t,r?function(e){for(var t=[],n=arguments.length-1;0<n--;)t[n]=arguments[n+1];return r.apply(void 0,t)}:e.handler),this.createDocumentElement()};function Xn(e){return e["[[CurrentInstanceId]]"]}Gn.prototype.getRef=function(e){return this.nodeMap[e]},Gn.prototype.open=function(){this.listener.batched=!1},Gn.prototype.close=function(){this.listener.batched=!0},Gn.prototype.createDocumentElement=function(){var n=this;if(!this.documentElement){var e=new An("document");e.docId=this.id,e.ownerDocument=this,e.role="documentElement",e.depth=0,e.ref="_documentElement",this.nodeMap._documentElement=e,this.documentElement=e,Object.defineProperty(e,"appendChild",{configurable:!0,enumerable:!0,writable:!0,value:function(e){mn(n,e)}}),Object.defineProperty(e,"insertBefore",{configurable:!0,enumerable:!0,writable:!0,value:function(e,t){mn(n,e,t)}}),on("debug")&&an('Create document element (id: "'+e.docId+'", ref: "'+e.ref+'")')}return this.documentElement},Gn.prototype.createBody=function(e,t){if(!this.body){var n=new An(e,t);yn(this,n),on("debug")&&an("[createBody]("+this.id+","+n.type+","+n.ref+") ("+JSON.stringify(n.toJSON(!0))+").")}return this.body},Gn.prototype.createElement=function(e,t){var n=new An(e,t);return on("debug")&&an("[createElement]("+this.id+","+n.type+","+n.ref+") ("+JSON.stringify(n.toJSON(!0))+")."),n},Gn.prototype.createComment=function(e){return new qn(e)},Gn.prototype.fireEvent=function(e,t,n,r,o){if(e){var i;(n=n||{}).type=n.type||t,n.target=e,n.currentTarget=e,n.timestamp=Date.now(),r&&function(e,t){var n=t.attrs||{};for(var r in n)e.setAttr(r,n[r],!0);var o=t.style||{};for(var i in o)e.setStyle(i,o[i],!0)}(e,r);var a=this.getRef("_root");return a&&a.attr&&(i="true"===a.attr.bubble),e.fireEvent(t,n,i,o)}},Gn.prototype.destroy=function(){var e;on("debug")&&an("[destroy]("+this.id+",document,"+this.ref+') Destroy document (id: "'+this.id+'", URL: "'+this.URL+'")'),this.taskCenter.destroyCallback(),delete this.listener,delete this.nodeMap,delete this.taskCenter,e=this.id,delete dn[e]},Gn.handler=null;var Kn,Zn,Yn=function(e,t,n){var r,o;r=this,o=String(e),Object.defineProperty(r,"[[CurrentInstanceId]]",{value:o}),this.config=t||{},this._nativeData=n||{},this.document=new Gn(e,this.config.bundleUrl),this.requireModule=this.requireModule.bind(this),this.importScript=this.importScript.bind(this),this.isRegisteredModule=Fn,this.isRegisteredComponent=Dn};Yn.prototype.requireModule=function(s){var c=Xn(this);if(c&&this.document&&this.document.taskCenter){if(Fn(s)){var e={},t=Tn[s],n=function(a){Object.defineProperty(e,a,{enumerable:!0,configurable:!0,get:function(){return n=s,r=a,(o=vn(e=c))&&"function"==typeof o.send?function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return o.send("module",{module:n,method:r},e)}:(console.error("[JS Framework] Failed to find taskCenter ("+e+")."),null);var e,n,r,o},set:function(e){return n=s,r=a,o=e,(i=vn(t=c))&&"function"==typeof i.send?"function"!=typeof o?(console.error("[JS Framework] "+n+"."+r+" must be assigned as a function."),null):function(e){return i.send("module",{module:n,method:r},[e])}:(console.error("[JS Framework] Failed to find taskCenter ("+t+")."),null);var t,n,r,o,i}})};for(var r in t)n(r);return e}console.warn('[JS Framework] using unregistered weex module "'+s+'"')}else console.error('[JS Framework] Failed to requireModule("'+s+'"), instance ('+c+") doesn't exist anymore.")},Yn.prototype.supports=function(e){if("string"!=typeof e)return null;var t=e.match(/^@(\w+)\/([\w-]+)(\.(\w+))?$/i);if(t){var n=t[1],r=t[2],o=t[4];switch(n){case"module":return Fn(r,o);case"component":return Dn(r)}}return null},Yn.prototype.importScript=function(e,r){void 0===r&&(r={});var o=Xn(this),i=vn(o);return new Promise(function(t,n){i&&"function"==typeof i.send||n(new Error('[JS Framework] Failed to import script "'+e+'", no taskCenter ('+o+") matched."));try{i.send("module",{module:"script",method:"importScript"},[e,r],{callback:[function(e){return t(e)},function(e){return n(e)}]})}catch(e){n(e)}})};var Qn=/^\s*\/\/ *(\{[^}]*\}) *\r?\n/;function er(){return"0.29.1"}var tr={};function nr(e){return tr[e]}function rr(e,t,n){void 0===t&&(t={});var r=new Yn(e,t,n),o=t.bundleType||"Vue";tr[e]=o;var i=Zn.frameworks[o];if(!i)return new Error('[JS Framework] Invalid bundle type "'+o+'".');var a,s,c,l,u=(a=e,s={weex:r,config:t,created:Date.now(),framework:o,bundleType:o},c=Zn,(l=Object.create(null)).service=Object.create(null),Vn.forEach(function(e){var t=e.name,n=e.options.create;if(n)try{var r=n(a,s,c);Object.assign(l.service,r),Object.assign(l,r.instance)}catch(e){console.error("[JS Runtime] Failed to create service "+t+".")}}),delete l.service.instance,Object.freeze(l.service),l);Object.freeze(u);var f=Object.create(null);Object.assign(f,u,{weex:r,getJSFMVersion:er,requireModule:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return r.requireModule.apply(r,e)},__WEEX_CALL_JAVASCRIPT__:Mn,services:u}),Object.freeze(f);var p=Object.assign({},f);return"function"==typeof i.createInstanceContext&&Object.assign(p,i.createInstanceContext(e,f,n)),Object.freeze(p),p}var or={createInstance:function(e,t,n,r){if(tr[e])return new Error('The instance id "'+e+'" has already been used!');var o=function(e){var t=Qn.exec(e);if(t)try{return JSON.parse(t[1]).framework}catch(e){}return"Weex"}(t);tr[e]=o,(n=JSON.parse(JSON.stringify(n||{}))).env=JSON.parse(JSON.stringify(global.WXEnvironment||{})),n.bundleType=o;var i=Zn.frameworks[o];if(!i)return new Error('[JS Framework] Invalid bundle type "'+o+'".');"Weex"===o&&console.error('[JS Framework] COMPATIBILITY WARNING: Weex DSL 1.0 (.we) framework is no longer supported! It will be removed in the next version of WeexSDK, your page would be crash if you still using the ".we" framework. Please upgrade it to Vue.js or Rax.');var a=rr(e,n,r);if("function"==typeof i.createInstance){if("Rax"!==o&&"Weex"!==o)return i.createInstance(e,t,n,r,a);var s=Object.assign({config:n,created:Date.now(),framework:o},a);return i.createInstance(e,t,n,r,s)}!function(e,t){var n=[],r=[];for(var o in t)n.push(o),r.push(t[o]);var i="\n (function (global) {\n "+e+"\n })(Object.create(this))\n ";(new(Function.prototype.bind.apply(Function,[null].concat(n,[i])))).apply(void 0,r)}(t,a)},createInstanceContext:rr,getRoot:function(e){var t=hn(e);try{if(t&&t.body)return t.body.toJSON()}catch(e){return void console.error("[JS Framework] Failed to get the virtual dom tree.")}},getJSFMVersion:er,getDocument:hn,registerService:Ln,unregisterService:Jn,callJS:function(e,t){var n=Kn[nr(e)];return n&&"function"==typeof n.receiveTasks?n.receiveTasks(e,t):Mn(e,t)}};function ir(s){or[s]=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];var n,r=e[0],o=nr(r);if(o&&Kn[o]){var i=(n=Kn[o])[s].apply(n,e),a={framework:o};return"refreshInstance"===s?Vn.forEach(function(e){var t=e.options.refresh;t&&t(r,{info:a,runtime:Zn})}):"destroyInstance"===s&&(Vn.forEach(function(e){var t=e.options.destroy;t&&t(r,{info:a,runtime:Zn})}),delete tr[r]),i}return new Error('[JS Framework] Using invalid instance id "'+r+'" when calling '+s+".")}}function ar(o,i){or[o]=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];for(var n in"function"==typeof i&&i.apply(void 0,e),Zn.frameworks){var r=Zn.frameworks[n];r&&r[o]&&r[o].apply(r,e)}}}var sr={Document:Gn,Element:An,Comment:qn,Listener:Un,TaskCenter:jn,sendTasks:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return"function"==typeof callNative?callNative.apply(void 0,e):(global.callNative||function(){}).apply(void 0,e)}};Gn.handler=sr.sendTasks;var cr={service:{register:Ln,unregister:Jn,has:Wn},freezePrototype:function(){Object.freeze(sr.Comment),Object.freeze(sr.Listener),Object.freeze(sr.Document.prototype),Object.freeze(sr.Comment.prototype),Object.freeze(sr.Listener.prototype)},init:function(e){for(var t in Kn=(Zn=e||{}).frameworks||{},function(){var e={createFinish:global.callCreateFinish,updateFinish:global.callUpdateFinish,refreshFinish:global.callRefreshFinish,createBody:global.callCreateBody,addElement:global.callAddElement,removeElement:global.callRemoveElement,moveElement:global.callMoveElement,updateAttrs:global.callUpdateAttrs,updateStyle:global.callUpdateStyle,addEvent:global.callAddEvent,removeEvent:global.callRemoveEvent,__updateComponentData:global.__updateComponentData},t=jn.prototype,n=function(n){var r=e[n];t[n]=r?function(e,t){return r.apply(void 0,[e].concat(t))}:function(e,t){return In(e,[{module:"dom",method:n,args:t}],"-1")}};for(var r in e)n(r);t.componentHandler=global.callNativeComponent||function(e,t,n,r,o){return In(e,[{component:o.component,ref:t,method:n,args:r}])},t.moduleHandler=global.callNativeModule||function(e,t,n,r){return In(e,[{module:t,method:n,args:r}])}}(),Kn){var n=Kn[t];if("function"==typeof n.init)try{n.init(e)}catch(e){}}return ar("registerComponents",Rn),ar("registerModules",Pn),ar("registerMethods"),["destroyInstance","refreshInstance"].forEach(ir),or},config:sr};function lr(e,t){void 0===t&&(t={}),this.type=e||"message",this.data=t.data||null,this.origin=t.origin||"",this.source=t.source||null,this.ports=t.ports||[],this.target=null,this.timeStamp=Date.now()}var ur={},fr={};function pr(){}pr.prototype.postMessage=function(e){if(this._closed)throw new Error('BroadcastChannel "'+this.name+'" is closed.');var t=ur[this.name];if(t&&t.length)for(var n=0;n<t.length;++n){var r=t[n];r._closed||r===this||"function"==typeof r.onmessage&&r.onmessage(new lr("message",{data:e}))}},pr.prototype.close=function(){var t=this;if(!this._closed&&(this._closed=!0,ur[this.name])){var e=ur[this.name].filter(function(e){return e!==t});e.length?ur[this.name]=e:delete ur[this.name]}};var dr={BroadcastChannel:{create:function(t,e,n){if(fr[t]=[],"function"==typeof global.BroadcastChannel)return{};var r={BroadcastChannel:function(e){Object.defineProperty(this,"name",{configurable:!1,enumerable:!0,writable:!1,value:String(e)}),this._closed=!1,this.onmessage=null,ur[this.name]||(ur[this.name]=[]),ur[this.name].push(this),fr[t].push(this)}};return r.BroadcastChannel.prototype=pr.prototype,{instance:r}},destroy:function(e,t){fr[e].forEach(function(e){return e.close()}),delete fr[e]}}};var hr={},vr={};var mr=Object.freeze({init:function(e){hr.Document=e.Document,hr.Element=e.Element,hr.Comment=e.Comment,hr.sendTasks=e.sendTasks},createInstance:function(t,e,n,r,o){void 0===n&&(n={}),void 0===r&&(r={}),void 0===o&&(o={});var i=new hr.Document(t,n.bundleUrl),a={},s={id:t,data:r,document:i,callbacks:a},c=0;i.addCallback=function(e){return a[++c]=e,c},i.handleCallback=function(e,t,n){var r=a[e];return n&&delete a[e],r(t)},vr[t]=s;var l=Object.assign({Document:hr.Document,Element:hr.Element,Comment:hr.Comment,sendTasks:function(e){return hr.sendTasks(t,e,-1)},options:n,document:i},o),u=[],f=[];for(var p in l)u.push(p),f.push(l[p]);return u.push(e),(new(Function.prototype.bind.apply(Function,[null].concat(u)))).apply(void 0,f),hr.sendTasks(t,[{module:"dom",method:"createFinish",args:[]}],-1),s},destroyInstance:function(e){delete vr[e]},getRoot:function(e){return vr[e].document.body.toJSON()},receiveTasks:function(r,e){var o={fireEvent:function(e,t,n,r,o){var i=vr[e].document,a=i.getRef(t);return i.fireEvent(a,n,r,o)},callback:function(e,t,n,r){return vr[e].document.handleCallback(t,n,r)}};if((vr[r]||{}).document&&Array.isArray(e)){var i=[];return e.forEach(function(e){var t=o[e.method],n=[].concat(e.args);"function"==typeof t&&(n.unshift(r),i.push(t.apply(void 0,n)))}),i}}}),yr=n(function(e){e.exports=function(e,o){var _=Object.freeze({});function $(e){return null==e}function A(e){return null!=e}function I(e){return!0===e}function j(e){return"string"==typeof e||"number"==typeof e||"symbol"==typeof e||"boolean"==typeof e}function b(e){return null!==e&&"object"==typeof e}var r=Object.prototype.toString;function u(e){return"[object Object]"===r.call(e)}function i(e){var t=parseFloat(String(e));return 0<=t&&Math.floor(t)===t&&isFinite(e)}function t(e){return null==e?"":"object"==typeof e?JSON.stringify(e,null,2):String(e)}function n(e){var t=parseFloat(e);return isNaN(t)?e:t}function s(e,t){for(var n=Object.create(null),r=e.split(","),o=0;o<r.length;o++)n[r[o]]=!0;return t?function(e){return n[e.toLowerCase()]}:function(e){return n[e]}}s("slot,component",!0);var c=s("key,ref,slot,slot-scope,is");function l(e,t){if(e.length){var n=e.indexOf(t);if(-1<n)return e.splice(n,1)}}var a=Object.prototype.hasOwnProperty;function f(e,t){return a.call(e,t)}function p(t){var n=Object.create(null);return function(e){return n[e]||(n[e]=t(e))}}var d=/-(\w)/g,h=p(function(e){return e.replace(d,function(e,t){return t?t.toUpperCase():""})}),v=p(function(e){return e.charAt(0).toUpperCase()+e.slice(1)}),m=/\B([A-Z])/g,w=p(function(e){return e.replace(m,"-$1").toLowerCase()});var y=Function.prototype.bind?function(e,t){return e.bind(t)}:function(n,r){function e(e){var t=arguments.length;return t?1<t?n.apply(r,arguments):n.call(r,e):n.call(r)}return e._length=n.length,e};function g(e,t){t=t||0;for(var n=e.length-t,r=new Array(n);n--;)r[n]=e[n+t];return r}function N(e,t){for(var n in t)e[n]=t[n];return e}function R(e,t,n){}var k=function(e,t,n){return!1},S=function(e){return e};function O(t,n){if(t===n)return!0;var e=b(t),r=b(n);if(!e||!r)return!e&&!r&&String(t)===String(n);try{var o=Array.isArray(t),i=Array.isArray(n);if(o&&i)return t.length===n.length&&t.every(function(e,t){return O(e,n[t])});if(o||i)return!1;var a=Object.keys(t),s=Object.keys(n);return a.length===s.length&&a.every(function(e){return O(t[e],n[e])})}catch(e){return!1}}function C(e,t){for(var n=0;n<e.length;n++)if(O(e[n],t))return n;return-1}function D(e){var t=!1;return function(){t||(t=!0,e.apply(this,arguments))}}var M="data-server-rendered",x=["component","directive","filter"],E=["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed","activated","deactivated","errorCaptured"],T={optionMergeStrategies:Object.create(null),silent:!1,productionTip:!1,devtools:!1,performance:!1,errorHandler:null,warnHandler:null,ignoredElements:[],keyCodes:Object.create(null),isReservedTag:k,isReservedAttr:k,isUnknownElement:k,getTagNamespace:R,parsePlatformTagName:S,mustUseProp:k,_lifecycleHooks:E};function P(e,t,n,r){Object.defineProperty(e,t,{value:n,enumerable:!!r,writable:!0,configurable:!0})}var F=/[^\w.$]/;var V,L="__proto__"in{},J="undefined"!=typeof window,W="undefined"!=typeof WXEnvironment&&!!WXEnvironment.platform,q=W&&WXEnvironment.platform.toLowerCase(),B=J&&window.navigator.userAgent.toLowerCase(),U=(B&&/msie|trident/.test(B),B&&0<B.indexOf("msie 9.0")),z=B&&0<B.indexOf("edge/"),H=(B&&B.indexOf("android"),B&&/iphone|ipad|ipod|ios/.test(B)||"ios"===q),G=(B&&/chrome\/\d+/.test(B),{}.watch);if(J)try{var X={};Object.defineProperty(X,"passive",{get:function(){}}),window.addEventListener("test-passive",null,X)}catch(e){}var K=function(){return void 0===V&&(V=!J&&!W&&void 0!==global&&"server"===global.process.env.VUE_ENV),V},Z=J&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function Y(e){return"function"==typeof e&&/native code/.test(e.toString())}var Q,ee="undefined"!=typeof Symbol&&Y(Symbol)&&"undefined"!=typeof Reflect&&Y(Reflect.ownKeys);Q="undefined"!=typeof Set&&Y(Set)?Set:function(){function e(){this.set=Object.create(null)}return e.prototype.has=function(e){return!0===this.set[e]},e.prototype.add=function(e){this.set[e]=!0},e.prototype.clear=function(){this.set=Object.create(null)},e}();var te=R,ne=0,re=function(){this.id=ne++,this.subs=[]};re.prototype.addSub=function(e){this.subs.push(e)},re.prototype.removeSub=function(e){l(this.subs,e)},re.prototype.depend=function(){re.target&&re.target.addDep(this)},re.prototype.notify=function(){for(var e=this.subs.slice(),t=0,n=e.length;t<n;t++)e[t].update()},re.target=null;var oe=[];function ie(e){re.target&&oe.push(re.target),re.target=e}function ae(){re.target=oe.pop()}var se=function(e,t,n,r,o,i,a,s){this.tag=e,this.data=t,this.children=n,this.text=r,this.elm=o,this.ns=void 0,this.context=i,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=t&&t.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=s,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1},ce={child:{configurable:!0}};ce.child.get=function(){return this.componentInstance},Object.defineProperties(se.prototype,ce);var le=function(e){void 0===e&&(e="");var t=new se;return t.text=e,t.isComment=!0,t};function ue(e){return new se(void 0,void 0,void 0,String(e))}function fe(e){var t=new se(e.tag,e.data,e.children,e.text,e.elm,e.context,e.componentOptions,e.asyncFactory);return t.ns=e.ns,t.isStatic=e.isStatic,t.key=e.key,t.isComment=e.isComment,t.fnContext=e.fnContext,t.fnOptions=e.fnOptions,t.fnScopeId=e.fnScopeId,t.isCloned=!0,t}var pe=Array.prototype,de=Object.create(pe);["push","pop","shift","unshift","splice","sort","reverse"].forEach(function(a){var s=pe[a];P(de,a,function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];var r,o=s.apply(this,t),i=this.__ob__;switch(a){case"push":case"unshift":r=t;break;case"splice":r=t.slice(2)}return r&&i.observeArray(r),i.dep.notify(),o})});var he=Object.getOwnPropertyNames(de),ve=!0;function me(e){ve=e}var ye=function(e){(this.value=e,this.dep=new re,this.vmCount=0,P(e,"__ob__",this),Array.isArray(e))?((L?ge:_e)(e,de,he),this.observeArray(e)):this.walk(e)};function ge(e,t,n){e.__proto__=t}function _e(e,t,n){for(var r=0,o=n.length;r<o;r++){var i=n[r];P(e,i,t[i])}}function be(e,t){var n;if(b(e)&&!(e instanceof se))return f(e,"__ob__")&&e.__ob__ instanceof ye?n=e.__ob__:ve&&!K()&&(Array.isArray(e)||u(e))&&Object.isExtensible(e)&&!e._isVue&&(n=new ye(e)),t&&n&&n.vmCount++,n}function we(n,e,r,t,o){var i=new re,a=Object.getOwnPropertyDescriptor(n,e);if(!a||!1!==a.configurable){var s=a&&a.get;s||2!==arguments.length||(r=n[e]);var c=a&&a.set,l=!o&&be(r);Object.defineProperty(n,e,{enumerable:!0,configurable:!0,get:function(){var e=s?s.call(n):r;return re.target&&(i.depend(),l&&(l.dep.depend(),Array.isArray(e)&&function e(t){for(var n=void 0,r=0,o=t.length;r<o;r++)(n=t[r])&&n.__ob__&&n.__ob__.dep.depend(),Array.isArray(n)&&e(n)}(e))),e},set:function(e){var t=s?s.call(n):r;e===t||e!=e&&t!=t||(c?c.call(n,e):r=e,l=!o&&be(e),i.notify())}})}}function ke(e,t,n){if(Array.isArray(e)&&i(t))return e.length=Math.max(e.length,t),e.splice(t,1,n),n;if(t in e&&!(t in Object.prototype))return e[t]=n;var r=e.__ob__;return e._isVue||r&&r.vmCount?n:r?(we(r.value,t,n),r.dep.notify(),n):e[t]=n}function Se(e,t){if(Array.isArray(e)&&i(t))e.splice(t,1);else{var n=e.__ob__;e._isVue||n&&n.vmCount||f(e,t)&&(delete e[t],n&&n.dep.notify())}}ye.prototype.walk=function(e){for(var t=Object.keys(e),n=0;n<t.length;n++)we(e,t[n])},ye.prototype.observeArray=function(e){for(var t=0,n=e.length;t<n;t++)be(e[t])};var Oe=T.optionMergeStrategies;function Ce(e,t){if(!t)return e;for(var n,r,o,i=Object.keys(t),a=0;a<i.length;a++)r=e[n=i[a]],o=t[n],f(e,n)?u(r)&&u(o)&&Ce(r,o):ke(e,n,o);return e}function xe(n,r,o){return o?function(){var e="function"==typeof r?r.call(o,o):r,t="function"==typeof n?n.call(o,o):n;return e?Ce(e,t):t}:r?n?function(){return Ce("function"==typeof r?r.call(this,this):r,"function"==typeof n?n.call(this,this):n)}:r:n}function Ee(e,t){return t?e?e.concat(t):Array.isArray(t)?t:[t]:e}function $e(e,t,n,r){var o=Object.create(e||null);return t?N(o,t):o}Oe.data=function(e,t,n){return n?xe(e,t,n):t&&"function"!=typeof t?e:xe(e,t)},E.forEach(function(e){Oe[e]=Ee}),x.forEach(function(e){Oe[e+"s"]=$e}),Oe.watch=function(e,t,n,r){if(e===G&&(e=void 0),t===G&&(t=void 0),!t)return Object.create(e||null);if(!e)return t;var o={};for(var i in N(o,e),t){var a=o[i],s=t[i];a&&!Array.isArray(a)&&(a=[a]),o[i]=a?a.concat(s):Array.isArray(s)?s:[s]}return o},Oe.props=Oe.methods=Oe.inject=Oe.computed=function(e,t,n,r){if(!e)return t;var o=Object.create(null);return N(o,e),t&&N(o,t),o},Oe.provide=xe;var Ae=function(e,t){return void 0===t?e:t};function Ie(n,r,o){"function"==typeof r&&(r=r.options),function(e,t){var n=e.props;if(n){var r,o,i={};if(Array.isArray(n))for(r=n.length;r--;)"string"==typeof(o=n[r])&&(i[h(o)]={type:null});else if(u(n))for(var a in n)o=n[a],i[h(a)]=u(o)?o:{type:o};e.props=i}}(r),function(e,t){var n=e.inject;if(n){var r=e.inject={};if(Array.isArray(n))for(var o=0;o<n.length;o++)r[n[o]]={from:n[o]};else if(u(n))for(var i in n){var a=n[i];r[i]=u(a)?N({from:i},a):{from:a}}}}(r),function(e){var t=e.directives;if(t)for(var n in t){var r=t[n];"function"==typeof r&&(t[n]={bind:r,update:r})}}(r);var e=r.extends;if(e&&(n=Ie(n,e,o)),r.mixins)for(var t=0,i=r.mixins.length;t<i;t++)n=Ie(n,r.mixins[t],o);var a,s={};for(a in n)c(a);for(a in r)f(n,a)||c(a);function c(e){var t=Oe[e]||Ae;s[e]=t(n[e],r[e],o,e)}return s}function je(e,t,n,r){if("string"==typeof n){var o=e[t];if(f(o,n))return o[n];var i=h(n);if(f(o,i))return o[i];var a=v(i);return f(o,a)?o[a]:o[n]||o[i]||o[a]}}function Me(e,t,n,r){var o=t[e],i=!f(n,e),a=n[e],s=Fe(Boolean,o.type);if(-1<s)if(i&&!f(o,"default"))a=!1;else if(""===a||a===w(e)){var c=Fe(String,o.type);(c<0||s<c)&&(a=!0)}if(void 0===a){a=function(e,t,n){if(!f(t,"default"))return;var r=t.default;if(e&&e.$options.propsData&&void 0===e.$options.propsData[n]&&void 0!==e._props[n])return e._props[n];return"function"==typeof r&&"Function"!==Te(t.type)?r.call(e):r}(r,o,e);var l=ve;me(!0),be(a),me(l)}return a}function Te(e){var t=e&&e.toString().match(/^\s*function (\w+)/);return t?t[1]:""}function Pe(e,t){return Te(e)===Te(t)}function Fe(e,t){if(!Array.isArray(t))return Pe(t,e)?0:-1;for(var n=0,r=t.length;n<r;n++)if(Pe(t[n],e))return n;return-1}function Ne(e,t,n){if(t)for(var r=t;r=r.$parent;){var o=r.$options.errorCaptured;if(o)for(var i=0;i<o.length;i++)try{if(!1===o[i].call(r,e,t,n))return}catch(e){Re(e,r,"errorCaptured hook")}}Re(e,t,n)}function Re(e,t,n){if(T.errorHandler)try{return T.errorHandler.call(null,e,t,n)}catch(e){De(e,null,"config.errorHandler")}De(e,t,n)}function De(e,t,n){if(!J&&!W||"undefined"==typeof console)throw e;console.error(e)}var Ve,Le,Je=[],We=!1;function qe(){We=!1;for(var e=Je.slice(0),t=Je.length=0;t<e.length;t++)e[t]()}var Be=!1;function Ue(){if("undefined"!=typeof setImmediate&&Y(setImmediate))Le=function(){setImmediate(qe)};else if("undefined"==typeof MessageChannel||!Y(MessageChannel)&&"[object MessageChannelConstructor]"!==MessageChannel.toString())Le=function(){setTimeout(qe,0)};else{var e=new MessageChannel,t=e.port2;e.port1.onmessage=qe,Le=function(){t.postMessage(1)}}if("undefined"!=typeof Promise&&Y(Promise)){var n=Promise.resolve();Ve=function(){n.then(qe),!W&&H&&setTimeout(R)}}else Ve=Le}function ze(e,t){var n;if(Je.push(function(){if(e)try{e.call(t)}catch(e){Ne(e,t,"nextTick")}else n&&n(t)}),We||(We=!0,Be&&"function"==typeof Le?Le():"function"==typeof Ve?Ve():setTimeout(qe,0)),!e&&"undefined"!=typeof Promise)return new Promise(function(e){n=e})}Ue();var He=new Q;function Ge(e){!function e(t,n){var r,o;var i=Array.isArray(t);if(!i&&!b(t)||Object.isFrozen(t)||t instanceof se)return;if(t.__ob__){var a=t.__ob__.dep.id;if(n.has(a))return;n.add(a)}if(i)for(r=t.length;r--;)e(t[r],n);else for(o=Object.keys(t),r=o.length;r--;)e(t[o[r]],n)}(e,He),He.clear()}var Xe,Ke=p(function(e){var t="&"===e.charAt(0),n="~"===(e=t?e.slice(1):e).charAt(0),r="!"===(e=n?e.slice(1):e).charAt(0);return{name:e=r?e.slice(1):e,once:n,capture:r,passive:t}});function Ze(e){function o(){var e=arguments,t=o.fns;if(!Array.isArray(t))return t.apply(null,arguments);for(var n=t.slice(),r=0;r<n.length;r++)n[r].apply(null,e)}return o.fns=e,o}function Ye(e,t,n,r,o){var i,a,s,c,l;for(i in e)a=s=e[i],c=t[i],l=Ke(i),u(a)&&(s=a.handler,l.params=a.params),$(s)||($(c)?($(s.fns)&&(s=e[i]=Ze(s)),n(l.name,s,l.once,l.capture,l.passive,l.params)):s!==c&&(c.fns=s,e[i]=c));for(i in t)$(e[i])&&r((l=Ke(i)).name,t[i],l.capture)}function Qe(e,t,n){var r;e instanceof se&&(e=e.data.hook||(e.data.hook={}));var o=e[t];function i(){n.apply(this,arguments),l(r.fns,i)}$(o)?r=Ze([i]):A(o.fns)&&I(o.merged)?(r=o).fns.push(i):r=Ze([o,i]),r.merged=!0,e[t]=r}function et(e,t,n,r,o){if(A(t)){if(f(t,n))return e[n]=t[n],o||delete t[n],!0;if(f(t,r))return e[n]=t[r],o||delete t[r],!0}return!1}function tt(e){return j(e)?[ue(e)]:Array.isArray(e)?function e(t,n){var r=[];var o,i,a,s;for(o=0;o<t.length;o++)$(i=t[o])||"boolean"==typeof i||(a=r.length-1,s=r[a],Array.isArray(i)?0<i.length&&(nt((i=e(i,(n||"")+"_"+o))[0])&&nt(s)&&(r[a]=ue(s.text+i[0].text),i.shift()),r.push.apply(r,i)):j(i)?nt(s)?r[a]=ue(s.text+i):""!==i&&r.push(ue(i)):nt(i)&&nt(s)?r[a]=ue(s.text+i.text):(I(t._isVList)&&A(i.tag)&&$(i.key)&&A(n)&&(i.key="__vlist"+n+"_"+o+"__"),r.push(i)));return r}(e):void 0}function nt(e){return A(e)&&A(e.text)&&!1===e.isComment}function rt(e,t){return(e.__esModule||ee&&"Module"===e[Symbol.toStringTag])&&(e=e.default),b(e)?t.extend(e):e}function ot(e){return e.isComment&&e.asyncFactory}function it(e){if(Array.isArray(e))for(var t=0;t<e.length;t++){var n=e[t];if(A(n)&&(A(n.componentOptions)||ot(n)))return n}}function at(e){e._events=Object.create(null),e._hasHookEvent=!1;var t=e.$options._parentListeners;t&<(e,t)}function st(e,t,n){n?Xe.$once(e,t):Xe.$on(e,t)}function ct(e,t){Xe.$off(e,t)}function lt(e,t,n){Xe=e,Ye(t,n||{},st,ct),Xe=void 0}function ut(e,t){var n={};if(!e)return n;for(var r=0,o=e.length;r<o;r++){var i=e[r],a=i.data;if(a&&a.attrs&&a.attrs.slot&&delete a.attrs.slot,i.context!==t&&i.fnContext!==t||!a||null==a.slot)(n.default||(n.default=[])).push(i);else{var s=a.slot,c=n[s]||(n[s]=[]);"template"===i.tag?c.push.apply(c,i.children||[]):c.push(i)}}for(var l in n)n[l].every(ft)&&delete n[l];return n}function ft(e){return e.isComment&&!e.asyncFactory||" "===e.text}function pt(e,t){t=t||{};for(var n=0;n<e.length;n++)Array.isArray(e[n])?pt(e[n],t):t[e[n].key]=e[n].fn;return t}var dt=null;function ht(e){var t=e.$options,n=t.parent;if(n&&!t.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(e)}e.$parent=n,e.$root=n?n.$root:e,e.$children=[],e.$refs={},e._watcher=null,e._inactive=null,e._directInactive=!1,e._isMounted=!1,e._isDestroyed=!1,e._isBeingDestroyed=!1}function vt(e){for(;e&&(e=e.$parent);)if(e._inactive)return!0;return!1}function mt(e,t){if(t){if(e._directInactive=!1,vt(e))return}else if(e._directInactive)return;if(e._inactive||null===e._inactive){e._inactive=!1;for(var n=0;n<e.$children.length;n++)mt(e.$children[n]);yt(e,"activated")}}function yt(t,n){ie();var e=t.$options[n];if(e)for(var r=0,o=e.length;r<o;r++)try{e[r].call(t)}catch(e){Ne(e,t,n+" hook")}t._hasHookEvent&&t.$emit("hook:"+n),ae()}var gt=[],_t=[],bt={},wt=!1,kt=!1,St=0;function Ot(){var e,t;for(kt=!0,gt.sort(function(e,t){return e.id-t.id}),St=0;St<gt.length;St++)t=(e=gt[St]).id,bt[t]=null,e.run();var n=_t.slice(),r=gt.slice();St=gt.length=_t.length=0,wt=kt=!(bt={}),function(e){for(var t=0;t<e.length;t++)e[t]._inactive=!0,mt(e[t],!0)}(n),function(e){var t=e.length;for(;t--;){var n=e[t],r=n.vm;r._watcher===n&&r._isMounted&&yt(r,"updated")}}(r),Z&&T.devtools&&Z.emit("flush")}var Ct=0,xt=function(e,t,n,r,o){this.vm=e,o&&(e._watcher=this),e._watchers.push(this),r?(this.deep=!!r.deep,this.user=!!r.user,this.lazy=!!r.lazy,this.sync=!!r.sync):this.deep=this.user=this.lazy=this.sync=!1,this.cb=n,this.id=++Ct,this.active=!0,this.dirty=this.lazy,this.deps=[],this.newDeps=[],this.depIds=new Q,this.newDepIds=new Q,this.expression="","function"==typeof t?this.getter=t:(this.getter=function(e){if(!F.test(e)){var n=e.split(".");return function(e){for(var t=0;t<n.length;t++){if(!e)return;e=e[n[t]]}return e}}}(t),this.getter||(this.getter=function(){})),this.value=this.lazy?void 0:this.get()};xt.prototype.get=function(){var e;ie(this);var t=this.vm;try{e=this.getter.call(t,t)}catch(e){if(!this.user)throw e;Ne(e,t,'getter for watcher "'+this.expression+'"')}finally{this.deep&&Ge(e),ae(),this.cleanupDeps()}return e},xt.prototype.addDep=function(e){var t=e.id;this.newDepIds.has(t)||(this.newDepIds.add(t),this.newDeps.push(e),this.depIds.has(t)||e.addSub(this))},xt.prototype.cleanupDeps=function(){for(var e=this.deps.length;e--;){var t=this.deps[e];this.newDepIds.has(t.id)||t.removeSub(this)}var n=this.depIds;this.depIds=this.newDepIds,this.newDepIds=n,this.newDepIds.clear(),n=this.deps,this.deps=this.newDeps,this.newDeps=n,this.newDeps.length=0},xt.prototype.update=function(){this.lazy?this.dirty=!0:this.sync?this.run():function(e){var t=e.id;if(null==bt[t]){if(bt[t]=!0,kt){for(var n=gt.length-1;St<n&>[n].id>e.id;)n--;gt.splice(n+1,0,e)}else gt.push(e);wt||(wt=!0,ze(Ot))}}(this)},xt.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||b(e)||this.deep){var t=this.value;if(this.value=e,this.user)try{this.cb.call(this.vm,e,t)}catch(e){Ne(e,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,e,t)}}},xt.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},xt.prototype.depend=function(){for(var e=this.deps.length;e--;)this.deps[e].depend()},xt.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||l(this.vm._watchers,this);for(var e=this.deps.length;e--;)this.deps[e].removeSub(this);this.active=!1}};var Et={enumerable:!0,configurable:!0,get:R,set:R};function $t(e,t,n){Et.get=function(){return this[t][n]},Et.set=function(e){this[t][n]=e},Object.defineProperty(e,n,Et)}function At(e){e._watchers=[];var t=e.$options;t.props&&function(n,r){var o=n.$options.propsData||{},i=n._props={},a=n.$options._propKeys=[];n.$parent&&me(!1);var e=function(e){a.push(e);var t=Me(e,r,o,n);we(i,e,t),e in n||$t(n,"_props",e)};for(var t in r)e(t);me(!0)}(e,t.props),t.methods&&function(e,t){e.$options.props;for(var n in t)e[n]=null==t[n]?R:y(t[n],e)}(e,t.methods),t.data?function(e){var t=e.$options.data;u(t=e._data="function"==typeof t?It(t,e):t||{})||(t={});var n=Object.keys(t),r=e.$options.props,o=(e.$options.methods,n.length);for(;o--;){var i=n[o];r&&f(r,i)||(void 0,36!==(a=(i+"").charCodeAt(0))&&95!==a&&$t(e,"_data",i))}var a;be(t,!0)}(e):be(e._data={},!0),t.computed&&function(e,t){var n=e._computedWatchers=Object.create(null),r=K();for(var o in t){var i=t[o],a="function"==typeof i?i:i.get;r||(n[o]=new xt(e,a||R,R,jt)),o in e||Mt(e,o,i)}}(e,t.computed),t.watch&&t.watch!==G&&function(e,t){for(var n in t){var r=t[n];if(Array.isArray(r))for(var o=0;o<r.length;o++)Pt(e,n,r[o]);else Pt(e,n,r)}}(e,t.watch)}function It(e,t){ie();try{return e.call(t,t)}catch(e){return Ne(e,t,"data()"),{}}finally{ae()}}var jt={lazy:!0};function Mt(e,t,n){var r=!K();Et.set="function"==typeof n?(Et.get=r?Tt(t):n,R):(Et.get=n.get?r&&!1!==n.cache?Tt(t):n.get:R,n.set?n.set:R),Object.defineProperty(e,t,Et)}function Tt(t){return function(){var e=this._computedWatchers&&this._computedWatchers[t];if(e)return e.dirty&&e.evaluate(),re.target&&e.depend(),e.value}}function Pt(e,t,n,r){return u(n)&&(n=(r=n).handler),"string"==typeof n&&(n=e[n]),e.$watch(t,n,r)}function Ft(e){var t=e.$options.provide;t&&(e._provided="function"==typeof t?t.call(e):t)}function Nt(t){var n=Rt(t.$options.inject,t);n&&(me(!1),Object.keys(n).forEach(function(e){we(t,e,n[e])}),me(!0))}function Rt(t,e){if(t){for(var n=Object.create(null),r=ee?Reflect.ownKeys(t).filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}):Object.keys(t),o=0;o<r.length;o++){for(var i=r[o],a=t[i].from,s=e;s;){if(s._provided&&f(s._provided,a)){n[i]=s._provided[a];break}s=s.$parent}if(!s&&"default"in t[i]){var c=t[i].default;n[i]="function"==typeof c?c.call(e):c}}return n}}function Dt(e,t){var n,r,o,i,a;if(Array.isArray(e)||"string"==typeof e)for(n=new Array(e.length),r=0,o=e.length;r<o;r++)n[r]=t(e[r],r);else if("number"==typeof e)for(n=new Array(e),r=0;r<e;r++)n[r]=t(r+1,r);else if(b(e))for(i=Object.keys(e),n=new Array(i.length),r=0,o=i.length;r<o;r++)a=i[r],n[r]=t(e[a],a,r);return A(n)&&(n._isVList=!0),n}function Vt(e,t,n,r){var o,i=this.$scopedSlots[e];if(i)n=n||{},r&&(n=N(N({},r),n)),o=i(n)||t;else{var a=this.$slots[e];a&&(a._rendered=!0),o=a||t}var s=n&&n.slot;return s?this.$createElement("template",{slot:s},o):o}function Lt(e){return je(this.$options,"filters",e)||S}function Jt(e,t){return Array.isArray(e)?-1===e.indexOf(t):e!==t}function Wt(e,t,n,r,o){var i=T.keyCodes[t]||n;return o&&r&&!T.keyCodes[t]?Jt(o,r):i?Jt(i,e):r?w(r)!==t:void 0}function qt(n,r,o,i,a){if(o)if(b(o)){var s;Array.isArray(o)&&(o=function(e){for(var t={},n=0;n<e.length;n++)e[n]&&N(t,e[n]);return t}(o));var e=function(t){if("class"===t||"style"===t||c(t))s=n;else{var e=n.attrs&&n.attrs.type;s=i||T.mustUseProp(r,e,t)?n.domProps||(n.domProps={}):n.attrs||(n.attrs={})}t in s||(s[t]=o[t],a&&((n.on||(n.on={}))["update:"+t]=function(e){o[t]=e}))};for(var t in o)e(t)}else;return n}function Bt(e,t){var n=this._staticTrees||(this._staticTrees=[]),r=n[e];return r&&!t||zt(r=n[e]=this.$options.staticRenderFns[e].call(this._renderProxy,null,this),"__static__"+e,!1),r}function Ut(e,t,n){return zt(e,"__once__"+t+(n?"_"+n:""),!0),e}function zt(e,t,n){if(Array.isArray(e))for(var r=0;r<e.length;r++)e[r]&&"string"!=typeof e[r]&&Ht(e[r],t+"_"+r,n);else Ht(e,t,n)}function Ht(e,t,n){e.isStatic=!0,e.key=t,e.isOnce=n}function Gt(e,t){if(t)if(u(t)){var n=e.on=e.on?N({},e.on):{};for(var r in t){var o=n[r],i=t[r];n[r]=o?[].concat(o,i):i}}else;return e}function Xt(e){e._o=Ut,e._n=n,e._s=t,e._l=Dt,e._t=Vt,e._q=O,e._i=C,e._m=Bt,e._f=Lt,e._k=Wt,e._b=qt,e._v=ue,e._e=le,e._u=pt,e._g=Gt}function Kt(e,t,n,i,r){var a,s=r.options;f(i,"_uid")?(a=Object.create(i))._original=i:i=(a=i)._original;var o=I(s._compiled),c=!o;this.data=e,this.props=t,this.children=n,this.parent=i,this.listeners=e.on||_,this.injections=Rt(s.inject,i),this.slots=function(){return ut(n,i)},o&&(this.$options=s,this.$slots=this.slots(),this.$scopedSlots=e.scopedSlots||_),s._scopeId?this._c=function(e,t,n,r){var o=mn(a,e,t,n,r,c);return o&&!Array.isArray(o)&&(o.fnScopeId=s._scopeId,o.fnContext=i),o}:this._c=function(e,t,n,r){return mn(a,e,t,n,r,c)}}function Zt(e,t,n,r){var o=fe(e);return o.fnContext=n,o.fnOptions=r,t.slot&&((o.data||(o.data={})).slot=t.slot),o}function Yt(e,t){for(var n in t)e[h(n)]=t[n]}Xt(Kt.prototype);var Qt="@inRecycleList";function en(e,t,n,r){if(o&&o.taskCenter)return"function"==typeof o.taskCenter.registerHook?o.taskCenter.registerHook(e,t,n,r):void 0}function tn(e,n,t){if(b(n))if(t)e.$refs={};else{var r=e.$refs||{};Object.keys(n).forEach(function(e){var t=n[e];r[e]=1===t.length?t[0]:t}),e.$refs=r}}function nn(e,n,r,t){if(b(r)){var o=e.$refs||{};t?Object.keys(r).forEach(function(e){var t=r[e];o[e]&&(1===t.length&&Array.isArray(o[e])?delete o[e][n]:delete o[e])}):(Object.keys(r).forEach(function(e){var t=r[e];1===t.length?(Array.isArray(o[e])||(o[e]=[]),o[e][n]=t[0]):o[e]=t}),e.$refs=o)}}var rn=0;function on(e){var t=e.$options.data,n=e.$options.computed||{},r=e._data?Object.assign({},e._data):"function"==typeof t?It(t,e):t||{},o={};for(var i in n)o[i]=e[i];return Object.assign({},r,o)}function an(e){void 0===e&&(e={});var r=this,t=e.componentId;P(r,"_vmTemplate",e.vmTemplate),r._uid=t||"virtual-component-"+rn++,r._isVue=!0,e&&e._isComponent?xn(r,e):r.$options=Ie(En(r.constructor),e||{},r),ht((r._renderProxy=r)._self=r),at(r),yn(r),yt(r,"beforeCreate"),Nt(r),At(r),Ft(r),yt(r,"created"),en(t,"lifecycle","attach",function(e){tn(r,e&&e.refs),yt(r,"beforeMount"),new xt(r,function(){return on(r)},function(){return r._update(r._vnode,!1)}),r._isMounted=!0,yt(r,"mounted")}),en(t,"lifecycle","update",function(e){tn(r,e&&e.refs),r._update(r._vnode,!1)}),en(t,"lifecycle","syncState",function(e,t){if(u(t))for(var n in t)r[n]=t[n];return on(r)}),en(t,"lifecycle","detach",function(e){tn(r,e&&e.refs,!0),r.$destroy(),r._vmTemplate&&(r._vmTemplate.removeVirtualComponent(r._uid),delete r._vmTemplate)})}function sn(e){var t=this,n=t.$options.componentId;(t._isMounted&&yt(t,"beforeUpdate"),t._vnode=e,t._isMounted&&n)&&function(e,t,n){if(o&&o.taskCenter)"function"==typeof o.taskCenter.updateData&&o.taskCenter.updateData(e,t,n)}(n,on(t),function(){yt(t,"updated")})}function cn(e){void 0===e&&(e={});var t=this;t._uid="virtual-component-template-"+rn++,t._isVue=!0,e&&e._isComponent?xn(t,e):t.$options=Ie(En(t.constructor),e||{},t),at(t._self=t),yn(t),At(t),this.registerVirtualComponent()}function ln(e){var t,n,o,i;delete e.data.attrs[Qt],n=(t=e).componentOptions.Ctor,o=n.extend({}),i=o.prototype.$emit,o.prototype._init=an,o.prototype._update=sn,o.prototype.$emit=function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];var r=this._uid,o=this._vmTemplate;return r&&o&&(t.push(r),i.apply(o,t)),i.apply(this,t)},t.componentOptions.Ctor=n.extend({methods:{registerVirtualComponent:function(){var r=this;P(r,"_virtualComponents",{}),en(String(r._uid),"lifecycle","create",function(e,t){var n=new o({vmTemplate:r,componentId:e,propsData:t});return n._uid=e,r._virtualComponents&&(r._virtualComponents[e]=n),on(n)})},removeVirtualComponent:function(e){delete this._virtualComponents[e]}},destroyed:function(){delete this._virtualComponents}}),t.componentOptions.Ctor.prototype._init=cn,t.componentOptions.Ctor.prototype._update=R;var r=dn(e),a=r.$options["@render"];if(a)try{return a.call(r)}catch(e){Ne(e,r,"@render")}}var un={init:function(e,t,n,r){if(e.componentInstance&&!e.componentInstance._isDestroyed&&e.data.keepAlive){var o=e;un.prepatch(o,o)}else{(e.componentInstance=dn(e,dt,n,r)).$mount(t?e.elm:void 0,t)}},prepatch:function(e,t){var n=t.componentOptions;!function(e,t,n,r,o){var i=!!(o||e.$options._renderChildren||r.data.scopedSlots||e.$scopedSlots!==_);if(e.$options._parentVnode=r,e.$vnode=r,e._vnode&&(e._vnode.parent=r),e.$options._renderChildren=o,e.$attrs=r.data.attrs||_,e.$listeners=n||_,t&&e.$options.props){me(!1);for(var a=e._props,s=e.$options._propKeys||[],c=0;c<s.length;c++){var l=s[c],u=e.$options.props;a[l]=Me(l,u,t,e)}me(!0),e.$options.propsData=t}n=n||_;var f=e.$options._parentListeners;e.$options._parentListeners=n,lt(e,n,f),i&&(e.$slots=ut(o,r.context),e.$forceUpdate())}(t.componentInstance=e.componentInstance,n.propsData,n.listeners,t,n.children)},insert:function(e){var t,n=e.context,r=e.componentInstance;r._isMounted||(r._isMounted=!0,yt(r,"mounted")),e.data.keepAlive&&(n._isMounted?((t=r)._inactive=!1,_t.push(t)):mt(r,!0))},destroy:function(e){var t=e.componentInstance;t._isDestroyed||(e.data.keepAlive?function e(t,n){if(!(n&&(t._directInactive=!0,vt(t))||t._inactive)){t._inactive=!0;for(var r=0;r<t.$children.length;r++)e(t.$children[r]);yt(t,"deactivated")}}(t,!0):t.$destroy())}},fn=Object.keys(un);function pn(e,t,n,r,o){if(!$(e)){var i=n.$options._base;if(b(e)&&(e=i.extend(e)),"function"==typeof e){var a,s,c,l,u,f,p;if($(e.cid)&&void 0===(e=function(t,n,e){if(I(t.error)&&A(t.errorComp))return t.errorComp;if(A(t.resolved))return t.resolved;if(I(t.loading)&&A(t.loadingComp))return t.loadingComp;if(!A(t.contexts)){var r=t.contexts=[e],o=!0,i=function(){for(var e=0,t=r.length;e<t;e++)r[e].$forceUpdate()},a=D(function(e){t.resolved=rt(e,n),o||i()}),s=D(function(e){A(t.errorComp)&&(t.error=!0,i())}),c=t(a,s);return b(c)&&("function"==typeof c.then?$(t.resolved)&&c.then(a,s):A(c.component)&&"function"==typeof c.component.then&&(c.component.then(a,s),A(c.error)&&(t.errorComp=rt(c.error,n)),A(c.loading)&&(t.loadingComp=rt(c.loading,n),0===c.delay?t.loading=!0:setTimeout(function(){$(t.resolved)&&$(t.error)&&(t.loading=!0,i())},c.delay||200)),A(c.timeout)&&setTimeout(function(){$(t.resolved)&&s(null)},c.timeout))),o=!1,t.loading?t.loadingComp:t.resolved}t.contexts.push(e)}(a=e,i,n)))return s=a,c=t,l=n,u=r,f=o,(p=le()).asyncFactory=s,p.asyncMeta={data:c,context:l,children:u,tag:f},p;t=t||{},En(e),A(t.model)&&function(e,t){var n=e.model&&e.model.prop||"value",r=e.model&&e.model.event||"input";(t.props||(t.props={}))[n]=t.model.value;var o=t.on||(t.on={});A(o[r])?o[r]=[t.model.callback].concat(o[r]):o[r]=t.model.callback}(e.options,t);var d=function(e,t,n){var r=t.options.props;if(!$(r)){var o={},i=e.attrs,a=e.props;if(A(i)||A(a))for(var s in r){var c=w(s);et(o,a,s,c,!0)||et(o,i,s,c,!1)}return o}}(t,e);if(I(e.options.functional))return function(e,t,n,r,o){var i=e.options,a={},s=i.props;if(A(s))for(var c in s)a[c]=Me(c,s,t||_);else A(n.attrs)&&Yt(a,n.attrs),A(n.props)&&Yt(a,n.props);var l=new Kt(n,a,o,r,e),u=i.render.call(null,l._c,l);if(u instanceof se)return Zt(u,n,l.parent,i);if(Array.isArray(u)){for(var f=tt(u)||[],p=new Array(f.length),d=0;d<f.length;d++)p[d]=Zt(f[d],n,l.parent,i);return p}}(e,d,t,n,r);var h=t.on;if(t.on=t.nativeOn,I(e.options.abstract)){var v=t.slot;t={},v&&(t.slot=v)}!function(e){for(var t=e.hook||(e.hook={}),n=0;n<fn.length;n++){var r=fn[n];t[r]=un[r]}}(t);var m,y=e.options.name||o,g=new se("vue-component-"+e.cid+(y?"-"+y:""),t,void 0,void 0,void 0,n,{Ctor:e,propsData:d,listeners:h,tag:o,children:r},a);return(m=g).data.attrs&&Qt in m.data.attrs?ln(g):g}}}function dn(e,t,n,r){var o={_isComponent:!0,parent:t,_parentVnode:e,_parentElm:n||null,_refElm:r||null},i=e.data.inlineTemplate;return A(i)&&(o.render=i.render,o.staticRenderFns=i.staticRenderFns),new e.componentOptions.Ctor(o)}var hn=1,vn=2;function mn(e,t,n,r,o,i){return(Array.isArray(n)||j(n))&&(o=r,r=n,n=void 0),I(i)&&(o=vn),function(e,t,n,r,o){if(A(n)&&A(n.__ob__))return le();A(n)&&A(n.is)&&(t=n.is);if(!t)return le();Array.isArray(r)&&"function"==typeof r[0]&&((n=n||{}).scopedSlots={default:r[0]},r.length=0);o===vn?r=tt(r):o===hn&&(r=function(e){for(var t=0;t<e.length;t++)if(Array.isArray(e[t]))return Array.prototype.concat.apply([],e);return e}(r));var i,a;if("string"==typeof t){var s;a=e.$vnode&&e.$vnode.ns||T.getTagNamespace(t),i=T.isReservedTag(t)?new se(T.parsePlatformTagName(t),n,r,void 0,void 0,e):A(s=je(e.$options,"components",t))?pn(s,n,e,r,t):new se(t,n,r,void 0,void 0,e)}else i=pn(t,n,e,r);return Array.isArray(i)?i:A(i)?(A(a)&&function e(t,n,r){t.ns=n;"foreignObject"===t.tag&&(r=!(n=void 0));if(A(t.children))for(var o=0,i=t.children.length;o<i;o++){var a=t.children[o];A(a.tag)&&($(a.ns)||I(r)&&"svg"!==a.tag)&&e(a,n,r)}}(i,a),A(n)&&function(e){b(e.style)&&Ge(e.style);b(e.class)&&Ge(e.class)}(n),i):le()}(e,t,n,r,o)}function yn(o){o._vnode=null,o._staticTrees=null;var e=o.$options,t=o.$vnode=e._parentVnode,n=t&&t.context;o.$slots=ut(e._renderChildren,n),o.$scopedSlots=_,o._c=function(e,t,n,r){return mn(o,e,t,n,r,!1)},o.$createElement=function(e,t,n,r){return mn(o,e,t,n,r,!0)};var r=t&&t.data;we(o,"$attrs",r&&r.attrs||_,null,!0),we(o,"$listeners",e._parentListeners||_,null,!0)}var gn,_n,bn,wn,kn,Sn,On,Cn=0;function xn(e,t){var n=e.$options=Object.create(e.constructor.options),r=t._parentVnode;n.parent=t.parent,n._parentVnode=r,n._parentElm=t._parentElm,n._refElm=t._refElm;var o=r.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,t.render&&(n.render=t.render,n.staticRenderFns=t.staticRenderFns)}function En(e){var t=e.options;if(e.super){var n=En(e.super);if(n!==e.superOptions){e.superOptions=n;var r=function(e){var t,n=e.options,r=e.extendOptions,o=e.sealedOptions;for(var i in n)n[i]!==o[i]&&(t||(t={}),t[i]=$n(n[i],r[i],o[i]));return t}(e);r&&N(e.extendOptions,r),(t=e.options=Ie(n,e.extendOptions)).name&&(t.components[t.name]=e)}}return t}function $n(e,t,n){if(Array.isArray(e)){var r=[];n=Array.isArray(n)?n:[n],t=Array.isArray(t)?t:[t];for(var o=0;o<e.length;o++)(0<=t.indexOf(e[o])||n.indexOf(e[o])<0)&&r.push(e[o]);return r}return e}function An(e){this._init(e)}function In(e){e.cid=0;var a=1;e.extend=function(e){e=e||{};var t=this,n=t.cid,r=e._Ctor||(e._Ctor={});if(r[n])return r[n];var o=e.name||t.options.name,i=function(e){this._init(e)};return((i.prototype=Object.create(t.prototype)).constructor=i).cid=a++,i.options=Ie(t.options,e),i.super=t,i.options.props&&function(e){var t=e.options.props;for(var n in t)$t(e.prototype,"_props",n)}(i),i.options.computed&&function(e){var t=e.options.computed;for(var n in t)Mt(e.prototype,n,t[n])}(i),i.extend=t.extend,i.mixin=t.mixin,i.use=t.use,x.forEach(function(e){i[e]=t[e]}),o&&(i.options.components[o]=i),i.superOptions=t.options,i.extendOptions=e,i.sealedOptions=N({},i.options),r[n]=i}}function jn(e){return e&&(e.Ctor.options.name||e.tag)}function Mn(e,t){return Array.isArray(e)?-1<e.indexOf(t):"string"==typeof e?-1<e.split(",").indexOf(t):(n=e,"[object RegExp]"===r.call(n)&&e.test(t));var n}function Tn(e,t){var n=e.cache,r=e.keys,o=e._vnode;for(var i in n){var a=n[i];if(a){var s=jn(a.componentOptions);s&&!t(s)&&Pn(n,i,r,o)}}}function Pn(e,t,n,r){var o=e[t];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),e[t]=null,l(n,t)}An.prototype._init=function(e){var t=this;t._uid=Cn++,t._isVue=!0,e&&e._isComponent?xn(t,e):t.$options=Ie(En(t.constructor),e||{},t),ht((t._renderProxy=t)._self=t),at(t),yn(t),yt(t,"beforeCreate"),Nt(t),At(t),Ft(t),yt(t,"created"),t.$options.el&&t.$mount(t.$options.el)},gn=An,_n={get:function(){return this._data}},bn={get:function(){return this._props}},Object.defineProperty(gn.prototype,"$data",_n),Object.defineProperty(gn.prototype,"$props",bn),gn.prototype.$set=ke,gn.prototype.$delete=Se,gn.prototype.$watch=function(e,t,n){if(u(t))return Pt(this,e,t,n);(n=n||{}).user=!0;var r=new xt(this,e,t,n);return n.immediate&&t.call(this,r.value),function(){r.teardown()}},kn=/^hook:/,(wn=An).prototype.$on=function(e,t){if(Array.isArray(e))for(var n=0,r=e.length;n<r;n++)this.$on(e[n],t);else(this._events[e]||(this._events[e]=[])).push(t),kn.test(e)&&(this._hasHookEvent=!0);return this},wn.prototype.$once=function(e,t){var n=this;function r(){n.$off(e,r),t.apply(n,arguments)}return r.fn=t,n.$on(e,r),n},wn.prototype.$off=function(e,t){var n=this;if(!arguments.length)return n._events=Object.create(null),n;if(Array.isArray(e)){for(var r=0,o=e.length;r<o;r++)this.$off(e[r],t);return n}var i=n._events[e];if(!i)return n;if(!t)return n._events[e]=null,n;if(t)for(var a,s=i.length;s--;)if((a=i[s])===t||a.fn===t){i.splice(s,1);break}return n},wn.prototype.$emit=function(t){var n=this,e=n._events[t];if(e){e=1<e.length?g(e):e;for(var r=g(arguments,1),o=0,i=e.length;o<i;o++)try{e[o].apply(n,r)}catch(e){Ne(e,n,'event handler for "'+t+'"')}}return n},(Sn=An).prototype._update=function(e,t){var n=this;n._isMounted&&yt(n,"beforeUpdate");var r=n.$el,o=n._vnode,i=dt;(dt=n)._vnode=e,o?n.$el=n.__patch__(o,e):(n.$el=n.__patch__(n.$el,e,t,!1,n.$options._parentElm,n.$options._refElm),n.$options._parentElm=n.$options._refElm=null),dt=i,r&&(r.__vue__=null),n.$el&&(n.$el.__vue__=n),n.$vnode&&n.$parent&&n.$vnode===n.$parent._vnode&&(n.$parent.$el=n.$el)},Sn.prototype.$forceUpdate=function(){this._watcher&&this._watcher.update()},Sn.prototype.$destroy=function(){var e=this;if(!e._isBeingDestroyed){yt(e,"beforeDestroy"),e._isBeingDestroyed=!0;var t=e.$parent;!t||t._isBeingDestroyed||e.$options.abstract||l(t.$children,e),e._watcher&&e._watcher.teardown();for(var n=e._watchers.length;n--;)e._watchers[n].teardown();e._data.__ob__&&e._data.__ob__.vmCount--,e._isDestroyed=!0,e.__patch__(e._vnode,null),yt(e,"destroyed"),e.$off(),e.$el&&(e.$el.__vue__=null),e.$vnode&&(e.$vnode.parent=null)}},Xt((On=An).prototype),On.prototype.$nextTick=function(e){return ze(e,this)},On.prototype._render=function(){var t,n=this,e=n.$options,r=e.render,o=e._parentVnode;o&&(n.$scopedSlots=o.data.scopedSlots||_),n.$vnode=o;try{t=r.call(n._renderProxy,n.$createElement)}catch(e){Ne(e,n,"render"),t=n._vnode}return t instanceof se||(t=le()),t.parent=o,t};var Fn,Nn,Rn,Dn=[String,RegExp,Array],Vn={KeepAlive:{name:"keep-alive",abstract:!0,props:{include:Dn,exclude:Dn,max:[String,Number]},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var e in this.cache)Pn(this.cache,e,this.keys)},mounted:function(){var e=this;this.$watch("include",function(t){Tn(e,function(e){return Mn(t,e)})}),this.$watch("exclude",function(t){Tn(e,function(e){return!Mn(t,e)})})},render:function(){var e=this.$slots.default,t=it(e),n=t&&t.componentOptions;if(n){var r=jn(n),o=this.include,i=this.exclude;if(o&&(!r||!Mn(o,r))||i&&r&&Mn(i,r))return t;var a=this.cache,s=this.keys,c=null==t.key?n.Ctor.cid+(n.tag?"::"+n.tag:""):t.key;a[c]?(t.componentInstance=a[c].componentInstance,l(s,c),s.push(c)):(a[c]=t,s.push(c),this.max&&s.length>parseInt(this.max)&&Pn(a,s[0],s,this._vnode)),t.data.keepAlive=!0}return t||e&&e[0]}}};Fn=An,Rn={get:function(){return T}},Object.defineProperty(Fn,"config",Rn),Fn.util={warn:te,extend:N,mergeOptions:Ie,defineReactive:we},Fn.set=ke,Fn.delete=Se,Fn.nextTick=ze,Fn.options=Object.create(null),x.forEach(function(e){Fn.options[e+"s"]=Object.create(null)}),N((Fn.options._base=Fn).options.components,Vn),Fn.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(-1<t.indexOf(e))return this;var n=g(arguments,1);return n.unshift(this),"function"==typeof e.install?e.install.apply(e,n):"function"==typeof e&&e.apply(null,n),t.push(e),this},Fn.mixin=function(e){return this.options=Ie(this.options,e),this},In(Fn),Nn=Fn,x.forEach(function(n){Nn[n]=function(e,t){return t?("component"===n&&u(t)&&(t.name=t.name||e,t=this.options._base.extend(t)),"directive"===n&&"function"==typeof t&&(t={bind:t,update:t}),this.options[n+"s"][e]=t):this.options[n+"s"][e]}}),Object.defineProperty(An.prototype,"$isServer",{get:K}),Object.defineProperty(An.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(An,"FunctionalRenderContext",{value:Kt}),An.version="2.5.16";var Ln=1;function Jn(e){this.instanceId="",this.nodeId=Ln++,this.parentNode=null,this.nodeType=3,this.text=e}function Wn(e){return o.createElement(e)}var qn=Object.freeze({namespaceMap:{},createElement:Wn,createElementNS:function(e,t){return o.createElement(e+":"+t)},createTextNode:function(e){return new Jn(e)},createComment:function(e){return o.createComment(e)},insertBefore:function(e,t,n){if(3!==t.nodeType)e.insertBefore(t,n);else if("text"===e.type)e.setAttr("value",t.text),t.parentNode=e;else{var r=Wn("text");r.setAttr("value",t.text),e.insertBefore(r,n)}},removeChild:function(e,t){3!==t.nodeType?e.removeChild(t):e.setAttr("value","")},appendChild:function(e,t){if(3!==t.nodeType)e.appendChild(t);else if("text"===e.type)e.setAttr("value",t.text),t.parentNode=e;else{var n=Wn("text");n.setAttr("value",t.text),e.appendChild(n)}},parentNode:function(e){return e.parentNode},nextSibling:function(e){return e.nextSibling},tagName:function(e){return e.type},setTextContent:function(e,t){e.parentNode&&e.parentNode.setAttr("value",t)},setAttribute:function(e,t,n){e.setAttr(t,n)},setStyleScope:function(e,t){e.setAttr("@styleScope",t)}}),Bn={create:function(e,t){Un(t)},update:function(e,t){e.data.ref!==t.data.ref&&(Un(e,!0),Un(t))},destroy:function(e){Un(e,!0)}};function Un(e,t){var n=e.data.ref;if(A(n)){var r=e.context,o=e.componentInstance||e.elm,i=r.$refs;t?Array.isArray(i[n])?l(i[n],o):i[n]===o&&(i[n]=void 0):e.data.refInFor?Array.isArray(i[n])?i[n].indexOf(o)<0&&i[n].push(o):i[n]=[o]:i[n]=o}}s("html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,menuitem,summary,content,element,shadow,template,blockquote,iframe,tfoot"),s("svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view",!0);var zn=s("text,number,password,search,email,tel,url"),Hn=new se("",{},[]),Gn=["create","activate","update","remove","destroy"];function Xn(e,t){return e.key===t.key&&(e.tag===t.tag&&e.isComment===t.isComment&&A(e.data)===A(t.data)&&function(e,t){if("input"!==e.tag)return!0;var n,r=A(n=e.data)&&A(n=n.attrs)&&n.type,o=A(n=t.data)&&A(n=n.attrs)&&n.type;return r===o||zn(r)&&zn(o)}(e,t)||I(e.isAsyncPlaceholder)&&e.asyncFactory===t.asyncFactory&&$(t.asyncFactory.error))}function Kn(e,t,n){var r,o,i={};for(r=t;r<=n;++r)A(o=e[r].key)&&(i[o]=r);return i}var Zn={create:Yn,update:Yn,destroy:function(e){Yn(e,Hn)}};function Yn(e,t){(e.data.directives||t.data.directives)&&function(t,n){var e,r,o,i=t===Hn,a=n===Hn,s=er(t.data.directives,t.context),c=er(n.data.directives,n.context),l=[],u=[];for(e in c)r=s[e],o=c[e],r?(o.oldValue=r.value,tr(o,"update",n,t),o.def&&o.def.componentUpdated&&u.push(o)):(tr(o,"bind",n,t),o.def&&o.def.inserted&&l.push(o));if(l.length){var f=function(){for(var e=0;e<l.length;e++)tr(l[e],"inserted",n,t)};i?Qe(n,"insert",f):f()}u.length&&Qe(n,"postpatch",function(){for(var e=0;e<u.length;e++)tr(u[e],"componentUpdated",n,t)});if(!i)for(e in s)c[e]||tr(s[e],"unbind",t,t,a)}(e,t)}var Qn=Object.create(null);function er(e,t){var n,r,o,i=Object.create(null);if(!e)return i;for(n=0;n<e.length;n++)(r=e[n]).modifiers||(r.modifiers=Qn),(i[(o=r,o.rawName||o.name+"."+Object.keys(o.modifiers||{}).join("."))]=r).def=je(t.$options,"directives",r.name);return i}function tr(t,n,r,e,o){var i=t.def&&t.def[n];if(i)try{i(r.elm,t,r,e,o)}catch(e){Ne(e,r.context,"directive "+t.name+" "+n+" hook")}}var nr=[Bn,Zn];function rr(e,t){if(e.data.attrs||t.data.attrs){var n,r,o=t.elm,i=e.data.attrs||{},a=t.data.attrs||{};a.__ob__&&(a=t.data.attrs=N({},a));var s="function"==typeof o.setAttrs,c={};for(n in a)r=a[n],i[n]!==r&&(s?c[n]=r:o.setAttr(n,r));for(n in i)null==a[n]&&(s?c[n]=void 0:o.setAttr(n));s&&o.setAttrs(c)}}var or={create:rr,update:rr};function ir(e,t){var n=t.elm,r=t.context,o=t.data,i=e.data;if(o.staticClass||o.class||i&&(i.staticClass||i.class)){var a=[],s=i.staticClass;s&&a.push.apply(a,s),i.class&&a.push.apply(a,i.class);var c,l,u,f,p=[],d=o.staticClass;if(d&&p.push.apply(p,d),o.class&&p.push.apply(p,o.class),"function"==typeof n.setClassList)n.setClassList(p);else{var h=(c=a,l=p,u=r.$options.style||{},f={},l.forEach(function(e){var t=u[e];N(f,t)}),c.forEach(function(e){var t=u[e];for(var n in t)f.hasOwnProperty(n)||(f[n]="")}),f);if("function"==typeof n.setStyles)n.setStyles(h);else for(var v in h)n.setStyle(v,h[v])}}}var ar,sr,cr={create:ir,update:ir};function lr(t,e,n,r,o,i){if(r)console.log("Weex do not support event in bubble phase.");else{if(n){var a=e,s=ar;e=function(e){null!==(1===arguments.length?a(e):a.apply(null,arguments))&&ur(t,null,null,s)}}if(sr&&sr._virtualComponents){ar._context=sr;var c=e;e=function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];var r=(t[0]||{}).componentId,o=this._context;r&&this._context&&(o=(this._context._virtualComponents||{})[r]||o);try{!function(e,t,n){void 0===n&&(n=null);var r=e.fns;if(!Array.isArray(r))return"function"==typeof r?r.apply(n,t):e.apply(n,t);for(var o=r.slice(),i=0;i<o.length;i++)o[i].apply(n,t)}(c,t,o)}catch(e){Ne(e,o,"Failed to invoke virtual component handler ("+r+")")}}}ar.addEvent(t,e,i)}}function ur(e,t,n,r){(r||ar).removeEvent(e)}function fr(e,t){if(e.data.on||t.data.on){var n=t.data.on||{},r=e.data.on||{};ar=t.elm,sr=t.context,Ye(n,r,lr,ur,t.context),sr=ar=void 0}}var pr={create:fr,update:fr},dr=p(h);function hr(e,t){if(e.data.style||t.data.style){var n,r,o=t.elm,i=e.data.style||{},a=t.data.style||{},s=a.__ob__;Array.isArray(a)&&(a=t.data.style=function(e){for(var t={},n=0;n<e.length;n++)e[n]&&N(t,e[n]);return t}(a)),s&&(a=t.data.style=N({},a));var c="function"==typeof o.setStyles,l={};for(r in i)a[r]||(c?l[dr(r)]="":o.setStyle(dr(r),""));for(r in a)n=a[r],c?l[dr(r)]=n:o.setStyle(dr(r),n);c&&o.setStyles(l)}}var vr={create:function(e,t){if(t.data.staticStyle){var n=t.elm,r=t.data.staticStyle,o="function"==typeof n.setStyles,i={};for(var a in r)r[a]&&(o?i[dr(a)]=r[a]:n.setStyle(dr(a),r[a]));o&&n.setStyles(i),hr(e,t)}else hr(e,t)},update:hr};function mr(e){if(e){if("object"!=typeof e)return"string"==typeof e?yr(e):void 0;var t={};return!1!==e.css&&N(t,yr(e.name||"v")),N(t,e),t}}var yr=p(function(e){return{enterClass:e+"-enter",enterToClass:e+"-enter-to",enterActiveClass:e+"-enter-active",leaveClass:e+"-leave",leaveToClass:e+"-leave-to",leaveActiveClass:e+"-leave-active"}});J&&!U&&(void 0===window.ontransitionend&&window.onwebkittransitionend,void 0===window.onanimationend&&window.onwebkitanimationend);J&&window.requestAnimationFrame&&window.requestAnimationFrame.bind(window);function gr(e,n){var r=n.elm;r._leaveCb&&(r._leaveCb.cancelled=!0,r._leaveCb());var t=mr(n.data.transition);if(t&&!r._enterCb){for(var o=t.enterClass,i=t.enterToClass,a=t.enterActiveClass,s=t.appearClass,c=t.appearToClass,l=t.appearActiveClass,u=t.beforeEnter,f=t.enter,p=t.afterEnter,d=t.enterCancelled,h=t.beforeAppear,v=t.appear,m=t.afterAppear,y=t.appearCancelled,g=dt,_=dt.$vnode;_&&_.parent;)g=(_=_.parent).context;var b=!g._isMounted||!n.isRootInsert;if(!b||v||""===v){var w=b?s:o,k=b?c:i,S=b?l:a,O=b&&h||u,C=b&&"function"==typeof v?v:f,x=b&&m||p,E=b&&y||d,$=C&&1<(C._length||C.length),A=n.context.$options.style||{},I=A[w],j=A["@TRANSITION"]&&A["@TRANSITION"][S]||{},M=function(e,t,n,r,o,i){var a={},s=t[n],c=t[r],l=t[o];if(s)for(var u in s)a[u]=e.style[u];if(l)for(var f in l)0!==f.indexOf("transition")&&(a[f]=l[f]);c&&N(a,c);return a}(r,A,w,k,S,n.context),T=0<Object.keys(M).length,P=r._enterCb=D(function(){P.cancelled?E&&E(r):x&&x(r),r._enterCb=null});if(setTimeout(function(){var e=r.parentNode,t=e&&e._pending&&e._pending[n.key];(t&&t.context===n.context&&t.tag===n.tag&&t.elm._leaveCb&&t.elm._leaveCb(),C&&C(r,P),T)?n.context.$requireWeexModule("animation").transition(r.ref,{styles:M,duration:j.duration||0,delay:j.delay||0,timingFunction:j.timingFunction||"linear"},$?R:P):$||P()},16),O&&O(r),I)if("function"==typeof r.setStyles)r.setStyles(I);else for(var F in I)r.setStyle(F,I[F]);T||$||P()}}}var _r=function(e){var r,t,g={},n=e.modules,_=e.nodeOps;for(r=0;r<Gn.length;++r)for(g[Gn[r]]=[],t=0;t<n.length;++t)A(n[t][Gn[r]])&&g[Gn[r]].push(n[t][Gn[r]]);function i(e){var t=_.parentNode(e);A(t)&&_.removeChild(t,e)}function b(e,t,n,r,o,i,a){if(A(e.elm)&&A(i)&&(e=i[a]=fe(e)),e.isRootInsert=!o,!function(e,t,n,r){var o=e.data;if(A(o)){var i=A(e.componentInstance)&&o.keepAlive;if(A(o=o.hook)&&A(o=o.init)&&o(e,!1,n,r),A(e.componentInstance))return d(e,t),I(i)&&function(e,t,n,r){for(var o,i=e;i.componentInstance;)if(i=i.componentInstance._vnode,A(o=i.data)&&A(o=o.transition)){for(o=0;o<g.activate.length;++o)g.activate[o](Hn,i);t.push(i);break}f(n,e.elm,r)}(e,t,n,r),!0}}(e,t,n,r)){var s=e.data,c=e.children,l=e.tag;if(A(l)){e.elm=e.ns?_.createElementNS(e.ns,l):_.createElement(l,e),p(e);var u=A(s)&&I(s.appendAsTree);u||(A(s)&&v(e,t),f(n,e.elm,r)),h(e,c,t),u&&(A(s)&&v(e,t),f(n,e.elm,r))}else I(e.isComment)?e.elm=_.createComment(e.text):e.elm=_.createTextNode(e.text),f(n,e.elm,r)}}function d(e,t){A(e.data.pendingInsert)&&(t.push.apply(t,e.data.pendingInsert),e.data.pendingInsert=null),e.elm=e.componentInstance.$el,w(e)?(v(e,t),p(e)):(Un(e),t.push(e))}function f(e,t,n){A(e)&&(A(n)?n.parentNode===e&&_.insertBefore(e,t,n):_.appendChild(e,t))}function h(e,t,n){if(Array.isArray(t))for(var r=0;r<t.length;++r)b(t[r],n,e.elm,null,!0,t,r);else j(e.text)&&_.appendChild(e.elm,_.createTextNode(String(e.text)))}function w(e){for(;e.componentInstance;)e=e.componentInstance._vnode;return A(e.tag)}function v(e,t){for(var n=0;n<g.create.length;++n)g.create[n](Hn,e);A(r=e.data.hook)&&(A(r.create)&&r.create(Hn,e),A(r.insert)&&t.push(e))}function p(e){var t;if(A(t=e.fnScopeId))_.setStyleScope(e.elm,t);else for(var n=e;n;)A(t=n.context)&&A(t=t.$options._scopeId)&&_.setStyleScope(e.elm,t),n=n.parent;A(t=dt)&&t!==e.context&&t!==e.fnContext&&A(t=t.$options._scopeId)&&_.setStyleScope(e.elm,t)}function y(e,t,n,r,o,i){for(;r<=o;++r)b(n[r],i,e,t,!1,n,r)}function k(e){var t,n,r=e.data;if(A(r))for(A(t=r.hook)&&A(t=t.destroy)&&t(e),t=0;t<g.destroy.length;++t)g.destroy[t](e);if(A(t=e.children))for(n=0;n<e.children.length;++n)k(e.children[n])}function S(e,t,n,r){for(;n<=r;++n){var o=t[n];A(o)&&(A(o.tag)?(a(o),k(o)):i(o.elm))}}function a(e,t){if(A(t)||A(e.data)){var n,r=g.remove.length+1;for(A(t)?t.listeners+=r:t=function(e,t){function n(){0==--n.listeners&&i(e)}return n.listeners=t,n}(e.elm,r),A(n=e.componentInstance)&&A(n=n._vnode)&&A(n.data)&&a(n,t),n=0;n<g.remove.length;++n)g.remove[n](e,t);A(n=e.data.hook)&&A(n=n.remove)?n(e,t):t()}else i(e.elm)}function O(e,t,n,r){for(var o=n;o<r;o++){var i=t[o];if(A(i)&&Xn(e,i))return o}}function C(e,t,n,r){if(e!==t){var o=t.elm=e.elm;if(I(e.isAsyncPlaceholder))A(t.asyncFactory.resolved)?E(e.elm,t,n):t.isAsyncPlaceholder=!0;else if(I(t.isStatic)&&I(e.isStatic)&&t.key===e.key&&(I(t.isCloned)||I(t.isOnce)))t.componentInstance=e.componentInstance;else{var i,a=t.data;A(a)&&A(i=a.hook)&&A(i=i.prepatch)&&i(e,t);var s=e.children,c=t.children;if(A(a)&&w(t)){for(i=0;i<g.update.length;++i)g.update[i](e,t);A(i=a.hook)&&A(i=i.update)&&i(e,t)}$(t.text)?A(s)&&A(c)?s!==c&&function(e,t,n,r,o){for(var i,a,s,c=0,l=0,u=t.length-1,f=t[0],p=t[u],d=n.length-1,h=n[0],v=n[d],m=!o;c<=u&&l<=d;)$(f)?f=t[++c]:$(p)?p=t[--u]:Xn(f,h)?(C(f,h,r),f=t[++c],h=n[++l]):Xn(p,v)?(C(p,v,r),p=t[--u],v=n[--d]):Xn(f,v)?(C(f,v,r),m&&_.insertBefore(e,f.elm,_.nextSibling(p.elm)),f=t[++c],v=n[--d]):(Xn(p,h)?(C(p,h,r),m&&_.insertBefore(e,p.elm,f.elm),p=t[--u]):($(i)&&(i=Kn(t,c,u)),$(a=A(h.key)?i[h.key]:O(h,t,c,u))?b(h,r,e,f.elm,!1,n,l):Xn(s=t[a],h)?(C(s,h,r),t[a]=void 0,m&&_.insertBefore(e,s.elm,f.elm)):b(h,r,e,f.elm,!1,n,l)),h=n[++l]);u<c?y(e,$(n[d+1])?null:n[d+1].elm,n,l,d,r):d<l&&S(0,t,c,u)}(o,s,c,n,r):A(c)?(A(e.text)&&_.setTextContent(o,""),y(o,null,c,0,c.length-1,n)):A(s)?S(0,s,0,s.length-1):A(e.text)&&_.setTextContent(o,""):e.text!==t.text&&_.setTextContent(o,t.text),A(a)&&A(i=a.hook)&&A(i=i.postpatch)&&i(e,t)}}}function x(e,t,n){if(I(n)&&A(e.parent))e.parent.data.pendingInsert=t;else for(var r=0;r<t.length;++r)t[r].data.hook.insert(t[r])}var m=s("attrs,class,staticClass,staticStyle,key");function E(e,t,n,r){var o,i=t.tag,a=t.data,s=t.children;if(r=r||a&&a.pre,t.elm=e,I(t.isComment)&&A(t.asyncFactory))return t.isAsyncPlaceholder=!0;if(A(a)&&(A(o=a.hook)&&A(o=o.init)&&o(t,!0),A(o=t.componentInstance)))return d(t,n),!0;if(A(i)){if(A(s))if(e.hasChildNodes())if(A(o=a)&&A(o=o.domProps)&&A(o=o.innerHTML)){if(o!==e.innerHTML)return!1}else{for(var c=!0,l=e.firstChild,u=0;u<s.length;u++){if(!l||!E(l,s[u],n,r)){c=!1;break}l=l.nextSibling}if(!c||l)return!1}else h(t,s,n);if(A(a)){var f=!1;for(var p in a)if(!m(p)){f=!0,v(t,n);break}!f&&a.class&&Ge(a.class)}}else e.data!==t.text&&(e.data=t.text);return!0}return function(e,t,n,r,o,i){if(!$(t)){var a,s=!1,c=[];if($(e))s=!0,b(t,c,o,i);else{var l=A(e.nodeType);if(!l&&Xn(e,t))C(e,t,c,r);else{if(l){if(1===e.nodeType&&e.hasAttribute(M)&&(e.removeAttribute(M),n=!0),I(n)&&E(e,t,c))return x(t,c,!0),e;a=e,e=new se(_.tagName(a).toLowerCase(),{},[],void 0,a)}var u=e.elm,f=_.parentNode(u);if(b(t,c,u._leaveCb?null:f,_.nextSibling(u)),A(t.parent))for(var p=t.parent,d=w(t);p;){for(var h=0;h<g.destroy.length;++h)g.destroy[h](p);if(p.elm=t.elm,d){for(var v=0;v<g.create.length;++v)g.create[v](Hn,p);var m=p.data.hook.insert;if(m.merged)for(var y=1;y<m.fns.length;y++)m.fns[y]()}else Un(p);p=p.parent}A(f)?S(0,[e],0,0):A(e.tag)&&k(e)}}return x(t,c,s),t.elm}A(e)&&k(e)}}({nodeOps:qn,modules:[or,cr,pr,vr,{create:gr,activate:gr,remove:function(n,e){var r=n.elm;r._enterCb&&(r._enterCb.cancelled=!0,r._enterCb());var t=mr(n.data.transition);if(!t)return e();if(r._leaveCb)return;var o=t.leaveClass,i=t.leaveToClass,a=t.leaveActiveClass,s=t.beforeLeave,c=t.leave,l=t.afterLeave,u=t.leaveCancelled,f=t.delayLeave,p=c&&1<(c._length||c.length),d=n.context.$options.style||{},h=d[o],v=d[i]||d[a],m=d["@TRANSITION"]&&d["@TRANSITION"][a]||{},y=r._leaveCb=D(function(){r.parentNode&&r.parentNode._pending&&(r.parentNode._pending[n.key]=null),y.cancelled?u&&u(r):(e(),l&&l(r)),r._leaveCb=null});f?f(g):g();function g(){var e=n.context.$requireWeexModule("animation");function t(){e.transition(r.ref,{styles:v,duration:m.duration||0,delay:m.delay||0,timingFunction:m.timingFunction||"linear"},p?R:y)}y.cancelled||(n.data.show||((r.parentNode._pending||(r.parentNode._pending={}))[n.key]=n),s&&s(r),h?e.transition(r.ref,{styles:h},t):t(),c&&c(r,y),v||p||y())}}}].concat(nr),LONG_LIST_THRESHOLD:10}),br=Object.getOwnPropertyNames(de);function wr(e,r){var o=e.$el;return o&&"function"==typeof o[r]?function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];return o[r].apply(o,t)}:(te("Can't find component method \""+r+'" on '+o.type),R)}function kr(n,r){Array.isArray(r)&&(!function(p,n){for(var e=function(e,t){var f=br[e];P(n,f,function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];var r=this.length,o=de[f];"function"==typeof o&&o.apply(this,t);var i=wr(p,"removeData"),a=wr(p,"insertRange"),s=wr(p,"setListData");switch(f){case"push":a(r,t);break;case"pop":i(r-1,1);break;case"shift":i(0,1);break;case"unshift":a(0,t);break;case"splice":var c=t[0],l=t[1],u=t.slice(2);0<l&&i(c,l),0<u.length&&a(c,u);break;case"sort":case"reverse":s(this.slice())}})},t=0,r=br.length;t<r;t++)e(t)}(n,r),r.forEach(function(t,e){u(t)&&!f(t,"[[Watched]]")&&(P(t,"[[Watched]]",!0),n.$watch(function(){for(var e in t)t[e]},function(){wr(n,"updateData")(r.indexOf(t),t)},{deep:!0}))}))}var Sr={name:"recycle-list",methods:{closest:function(){for(var e,t=arguments,n=[],r=arguments.length;r--;)n[r]=t[r];return(e=this.$el).closest.apply(e,n)},queryElement:function(){for(var e,t=arguments,n=[],r=arguments.length;r--;)n[r]=t[r];return(e=this.$el).queryElement.apply(e,n)},queryElementAll:function(){for(var e,t=arguments,n=[],r=arguments.length;r--;)n[r]=t[r];return(e=this.$el).queryElementAll.apply(e,n)},scrollToElement:function(){for(var e,t=arguments,n=[],r=arguments.length;r--;)n[r]=t[r];return(e=this.$el).scrollToElement.apply(e,n)},resetLoadmore:function(){for(var e,t=arguments,n=[],r=arguments.length;r--;)n[r]=t[r];return(e=this.$el).resetLoadmore.apply(e,n)}},render:function(e){var t=this;if(this._vnode&&this.$options["[[UseCache]]"])return P(this.$options,"[[UseCache]]",!1),this._vnode;var n=this.$options.parent,r=this.$attrs.bindingExpression;return n&&r&&(n.$watch(r,function(){return P(t.$options,"[[UseCache]]",!0)},{deep:!0,immediate:!0}),kr(this,this.$attrs.listData),n.$watch(r,function(e){kr(t,e)})),this._events._attach_slot=function(e){nn(t.$parent||t,e.position,e.refs)},this._events._detach_slot=function(e){nn(t.$parent||t,e.position,e.refs,!0)},e("weex:recycle-list",{on:this._events},this.$slots.default)},renderError:function(e,t){return e("text",{style:{fontSize:"36px",color:"#FF0000"},value:t.toString()})}};function Or(e){if(e.length)return e.map(function(e){var t,n,r=(t=e).tag?t.tag.replace(/vue\-component\-(\d+\-)?/,""):"",o={type:r};if(r){if(o.style=function(e){if(e&&e.data){var t=e.data,n=t.staticStyle,r=t.staticClass;if(e.data.style||e.data.class||n||r){var o=Object.assign({},n,e.data.style),i=e.context.$options.style||{};return[].concat(r,e.data.class).forEach(function(e){e&&i[e]&&Object.assign(o,i[e])}),o}}}(e),e.data&&(o.attr=e.data.attrs,e.data.on&&(o.events=e.data.on)),"span"===r&&((n=e).children&&1===n.children.length&&!n.children[0].tag))return o.attr=o.attr||{},o.attr.value=e.children[0].text.trim(),o}else o.type="span",o.attr={value:(e.text||"").trim()};return e.children&&e.children.length&&(o.children=Or(e.children)),o})}var Cr={name:"richtext",render:function(e){return e("weex:richtext",{on:this._events,attrs:{value:Or(this.$options._renderChildren||[])}})}},xr={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function Er(e){var t=e&&e.componentOptions;return t&&t.Ctor.options.abstract?Er(it(t.children)):e}function $r(e){var t={},n=e.$options;for(var r in n.propsData)t[r]=e[r];var o=n._parentListeners;for(var i in o)t[h(i)]=o[i];return t}function Ar(e,t){if(/\d-keep-alive$/.test(t.tag))return e("keep-alive",{props:t.componentOptions.propsData})}var Ir={name:"transition",props:xr,abstract:!0,render:function(e){var t=this,n=this.$slots.default;if(n&&(n=n.filter(function(e){return e.tag||ot(e)})).length){var r=this.mode,o=n[0];if(function(e){for(;e=e.parent;)if(e.data.transition)return!0}(this.$vnode))return o;var i=Er(o);if(!i)return o;if(this._leaving)return Ar(e,o);var a="__transition-"+this._uid+"-";i.key=null==i.key?i.isComment?a+"comment":a+i.tag:j(i.key)?0===String(i.key).indexOf(a)?i.key:a+i.key:i.key;var s,c,l=(i.data||(i.data={})).transition=$r(this),u=this._vnode,f=Er(u);if(i.data.directives&&i.data.directives.some(function(e){return"show"===e.name})&&(i.data.show=!0),f&&f.data&&(s=i,(c=f).key!==s.key||c.tag!==s.tag)&&!ot(f)&&(!f.componentInstance||!f.componentInstance._vnode.isComment)){var p=f.data.transition=N({},l);if("out-in"===r)return this._leaving=!0,Qe(p,"afterLeave",function(){t._leaving=!1,t.$forceUpdate()}),Ar(e,o);if("in-out"===r){if(ot(i))return u;var d,h=function(){d()};Qe(l,"afterEnter",h),Qe(l,"enterCancelled",h),Qe(p,"delayLeave",function(e){d=e})}}return o}}},jr=N({tag:String,moveClass:String},xr);delete jr.mode;var Mr={RecycleList:Sr,Richtext:Cr,Transition:Ir,TransitionGroup:{props:jr,created:function(){var e=this.$requireWeexModule("dom");this.getPosition=function(r){return new Promise(function(t,n){e.getComponentRect(r.ref,function(e){e.result?t(e.size):n(new Error("failed to get rect for element: "+r.tag))})})};var r=this.$requireWeexModule("animation");this.animate=function(t,n){return new Promise(function(e){r.transition(t.ref,n,e)})}},render:function(e){for(var t=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=$r(this),s=0;s<o.length;s++){var c=o[s];c.tag&&null!=c.key&&0!==String(c.key).indexOf("__vlist")&&(i.push(c),((n[c.key]=c).data||(c.data={})).transition=a)}if(r){var l=[],u=[];r.forEach(function(e){e.data.transition=a,n[e.key]?l.push(e):u.push(e)}),this.kept=e(t,null,l),this.removed=u}return e(t,null,i)},beforeUpdate:function(){this.__patch__(this._vnode,this.kept,!1,!0),this._vnode=this.kept},updated:function(){var e=this.prevChildren,t=this.moveClass||(this.name||"v")+"-move";e.length&&this.getMoveData(e[0].context,t)},methods:{getMoveData:function(e,t){var n=e.$options.style||{};return n["@TRANSITION"]&&n["@TRANSITION"][t]}}}},Tr=s("template,script,style,element,content,slot,link,meta,svg,view,a,div,img,image,text,span,input,switch,textarea,spinner,select,slider,slider-neighbor,indicator,canvas,list,cell,header,loading,loading-indicator,refresh,scrollable,scroller,video,web,embed,tabbar,tabheader,datepicker,timepicker,marquee,countdown",!0),Pr=(s("web,spinner,switch,video,textarea,canvas,indicator,marquee,countdown",!0),s("richtext,transition,transition-group,recycle-list",!0));s("embed,img,image,input,link,meta",!0);function Fr(e){return!(!e.$options||!e.$options.el)}An.mixin({beforeCreate:function(){Fr(this)&&Ue()},destroyed:function(){Fr(this)&&(Je.length=0,Le=Ve=null,Be=We=!1)}}),An.config.mustUseProp=function(e,t,n){return!1},An.config.isReservedTag=Tr,An.config.isRuntimeComponent=Pr,An.config.isUnknownElement=function(e){return!1},An.options.directives={},An.options.components=Mr,An.prototype.__patch__=_r,An.prototype.$mount=function(e,t){return n=this,r=e&&(i=this.$document,(a=i.createComment("root")).hasAttribute=a.removeAttribute=function(){},i.documentElement.appendChild(a),a),o=t,n.$el=r,n.$options.render||(n.$options.render=le),yt(n,"beforeMount"),new xt(n,function(){n._update(n._render(),o)},R,null,!0),o=!1,null==n.$vnode&&(n._isMounted=!0,yt(n,"mounted")),n;var n,r,o,i,a},e.Vue=An}});e(yr);var gr=n(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var f={};t.createInstanceContext=function(e,t,n){void 0===n&&(n={});var r,o,i,a,s=t.weex,c=(f[e]={instanceId:e,config:s.config,document:s.document,data:n}).Vue=function(e,t){var n={};yr(n,t.document);var r=n.Vue,o=f[e],i=/^weex:/i,a=r.config.isReservedTag||function(){return!1},s=r.config.isRuntimeComponent||function(){return!1};return r.config.isReservedTag=function(e){return!s(e)&&t.supports("@component/"+e)||a(e)||i.test(e)},r.config.parsePlatformTagName=function(e){return e.replace(i,"")},r.prototype.$instanceId=e,r.prototype.$document=o.document,r.prototype.$requireWeexModule=t.requireModule,r.mixin({beforeCreate:function(){var e=this.$options;if(e.el){var t=e.data,n=("function"==typeof t?t():t)||{};e.data=Object.assign(n,o.data),o.app=this}},mounted:function(){if(this.$options.el&&t.document&&o.app===this)try{t.document.taskCenter.send("dom",{action:"createFinish"},[])}catch(e){}}}),r.prototype.$getConfig=function(){if(o.app instanceof r)return o.config},r}(e,s),l=(r=e,o=s.requireModule,i=f[r],a=o("timer"),{setTimeout:function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];return a.setTimeout(function(){t[0].apply(t,t.slice(2))},t[1]),i.document.taskCenter.callbackManager.lastCallbackId.toString()},setInterval:function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];return a.setInterval(function(){t[0].apply(t,t.slice(2))},t[1]),i.document.taskCenter.callbackManager.lastCallbackId.toString()},clearTimeout:function(e){a.clearTimeout(e)},clearInterval:function(e){a.clearInterval(e)}}),u=Object.assign({Vue:c},l);return Object.freeze(u),u},t.destroyInstance=function(e){var t=f[e];if(t&&t.app instanceof t.Vue){try{t.app.$destroy(),t.document.destroy()}catch(e){}delete t.document,delete t.app}delete f[e]},t.refreshInstance=function(e,t){var n=f[e];if(!(n&&n.app instanceof n.Vue))return new Error("refreshInstance: instance "+e+" not found!");if(n.Vue&&n.Vue.set)for(var r in t)n.Vue.set(n.app,r,t[r]);n.document.taskCenter.send("dom",{action:"refreshFinish"},[])}}),_r=e(gr),br=gr.createInstanceContext,wr=gr.destroyInstance,kr=gr.refreshInstance,Sr=Object.freeze({default:_r,__moduleExports:gr,createInstanceContext:br,destroyInstance:wr,refreshInstance:kr});var Or=Object.freeze({$:function(e){console.warn("[JS Framework] Vm#$ is deprecated, please use Vm#$vm instead");var t=this._ids[e];if(t)return t.vm},$el:function(e){var t=this._ids[e];if(t)return t.el},$vm:function(e){var t=this._ids[e];if(t)return t.vm},$renderThen:function(e){return this._app.differ.then(function(){e()})},$scrollTo:function(e,t){console.warn("[JS Framework] Vm#$scrollTo is deprecated, please use \"require('@weex-module/dom').scrollTo(el, options)\" instead");var n=this.$el(e);n&&this._app.requireModule("dom").scrollToElement(n.ref,{offset:t})},$transition:function(e,n,r){var o=this,i=this.$el(e);i&&n&&n.styles&&this._app.requireModule("animation").transition(i.ref,n,function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];o._setStyle(i,n.styles),r&&r.apply(void 0,e)})},$getConfig:function(e){var t=this._app.options;return"function"==typeof e&&(console.warn("[JS Framework] the callback of Vm#$getConfig(callback) is deprecated, this api now can directly RETURN config info."),e(t)),t},$sendHttp:function(e,t){console.warn("[JS Framework] Vm#$sendHttp is deprecated, please use \"require('@weex-module/stream').sendHttp(params, callback)\" instead"),this._app.requireModule("stream").sendHttp(e,t)},$openURL:function(e){console.warn("[JS Framework] Vm#$openURL is deprecated, please use \"require('@weex-module/event').openURL(url)\" instead"),this._app.requireModule("event").openURL(e)},$setTitle:function(e){console.warn("[JS Framework] Vm#$setTitle is deprecated, please use \"require('@weex-module/pageInfo').setTitle(title)\" instead"),this._app.requireModule("pageInfo").setTitle(e)},$call:function(e,t){for(var n=[],r=arguments.length-2;0<r--;)n[r]=arguments[r+2];console.warn("[JS Framework] Vm#$call is deprecated, please use \"require('@weex-module/moduleName')\" instead");var o=this._app.requireModule(e);o&&o[t]&&o[t].apply(o,n)}});function Cr(e){for(var t=[],n=arguments.length-1;0<n--;)t[n]=arguments[n+1];if("function"==typeof Object.assign)Object.assign.apply(Object,[e].concat(t));else{var r=t.shift();for(var o in r)e[o]=r[o];t.length&&Cr.apply(void 0,[e].concat(t))}return e}function xr(e,t,n,r){Object.defineProperty(e,t,{value:n,enumerable:!!r,writable:!0,configurable:!0})}function Er(e,t){if(e.length){var n=e.indexOf(t);if(-1<n)return e.splice(n,1)}}var $r=Object.prototype.hasOwnProperty;function Ar(e,t){return $r.call(e,t)}function Ir(n,r){return function(e){var t=arguments.length;return t?1<t?n.apply(r,arguments):n.call(r,e):n.call(r)}}function jr(e){return null!==e&&"object"==typeof e}var Mr=Object.prototype.toString,Tr="[object Object]";function Pr(e){return Mr.call(e)===Tr}function Fr(e){var t=(e+"").charCodeAt(0);return 36===t||95===t}var Nr,Rr="__proto__"in{};function Dr(){return"object"==typeof nativeSet?nativeSet.create():new Nr}function Vr(e){var t=Object.prototype.toString.call(e);return t.substring(8,t.length-1).toLowerCase()}"undefined"!=typeof Set&&Set.toString().match(/native code/)?Nr=Set:((Nr=function(){this.set=Object.create(null)}).prototype.has=function(e){return void 0!==this.set[e]},Nr.prototype.add=function(e){null==e||this.set[e]||(this.set[e]=1)},Nr.prototype.clear=function(){this.set=Object.create(null)});var Lr=/^@weex-component\//,Jr=/^@weex-module\//,Wr=/^\.{1,2}\//,qr=/\.js$/,Br=function(e){return!!e.match(Lr)},Ur=function(e){return!!e.match(Jr)},zr=function(e){return!!e.match(Wr)},Hr=function(e){return!Br(e)&&!Ur(e)&&!zr(e)};function Gr(e){return e.replace(Lr,"").replace(Jr,"")}function Xr(e){return e.replace(qr,"")}var Kr=0;function Zr(){this.id=Kr++,this.subs=[]}Zr.target=null;var Yr=[];function Qr(){Zr.target=null,Yr=[]}Zr.prototype.addSub=function(e){this.subs.push(e)},Zr.prototype.removeSub=function(e){Er(this.subs,e)},Zr.prototype.depend=function(){Zr.target&&Zr.target.addDep(this)},Zr.prototype.notify=function(){for(var e=this.subs.slice(),t=0,n=e.length;t<n;t++)e[t].update()};var eo=0;function to(e,t,n,r){r&&Cr(this,r);var o="function"==typeof t;(this.vm=e)._watchers.push(this),this.expression=t,this.cb=n,this.id=++eo,this.active=!0,this.dirty=this.lazy,this.deps=[],this.newDeps=[],this.depIds=Dr(),this.newDepIds=Dr(),o&&(this.getter=t),this.value=this.lazy?void 0:this.get(),this.queued=this.shallow=!1}to.prototype.get=function(){var e;e=this,Zr.target&&Yr.push(Zr.target),Zr.target=e;var t=this.getter.call(this.vm,this.vm);return this.deep&&function e(t,n){var r,o,i,a;n||(n=no).clear();i=Array.isArray(t);a=jr(t);if(i||a){if(t.__ob__){var s=t.__ob__.dep.id;if(n.has(s))return;n.add(s)}if(i)for(r=t.length;r--;)e(t[r],n);else if(a)for(o=Object.keys(t),r=o.length;r--;)e(t[o[r]],n)}}(t),Zr.target=Yr.pop(),this.cleanupDeps(),t},to.prototype.addDep=function(e){var t=e.id;this.newDepIds.has(t)||(this.newDepIds.add(t),this.newDeps.push(e),this.depIds.has(t)||e.addSub(this))},to.prototype.cleanupDeps=function(){for(var e=this.deps.length;e--;){var t=this.deps[e];this.newDepIds.has(t.id)||t.removeSub(this)}var n=this.depIds;this.depIds=this.newDepIds,this.newDepIds=n,this.newDepIds.clear(),n=this.deps,this.deps=this.newDeps,this.newDeps=n,this.newDeps.length=0},to.prototype.update=function(e){this.lazy?this.dirty=!0:this.run()},to.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||(jr(e)||this.deep)&&!this.shallow){var t=this.value;this.value=e,this.cb.call(this.vm,e,t)}this.queued=this.shallow=!1}},to.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},to.prototype.depend=function(){for(var e=this.deps.length;e--;)this.deps[e].depend()},to.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||this.vm._vForRemoving||Er(this.vm._watchers,this);for(var e=this.deps.length;e--;)this.deps[e].removeSub(this);this.active=!1,this.vm=this.cb=this.value=null}};var no=Dr();var ro=Array.prototype,oo=Object.create(ro);["push","pop","shift","unshift","splice","sort","reverse"].forEach(function(a){var s=ro[a];xr(oo,a,function(){for(var e=arguments,t=arguments.length,n=new Array(t);t--;)n[t]=e[t];var r,o=s.apply(this,n),i=this.__ob__;switch(a){case"push":case"unshift":r=n;break;case"splice":r=n.slice(2)}return r&&i.observeArray(r),i.dep.notify(),o})}),xr(ro,"$set",function(e,t){return console.warn('[JS Framework] "Array.prototype.$set" is not a standard API, it will be removed in the next version.'),e>=this.length&&(this.length=e+1),this.splice(e,1,t)[0]}),xr(ro,"$remove",function(e){console.warn('[JS Framework] "Array.prototype.$remove" is not a standard API, it will be removed in the next version.'),this.length&&("number"!=typeof e&&(e=this.indexOf(e)),-1<e&&this.splice(e,1))});var io=Object.getOwnPropertyNames(oo);function ao(e){(this.value=e,this.dep=new Zr,xr(e,"__ob__",this),Array.isArray(e))?((Rr?so:co)(e,oo,io),this.observeArray(e)):this.walk(e)}function so(e,t){e.__proto__=t}function co(e,t,n){for(var r=0,o=n.length;r<o;r++){var i=n[r];xr(e,i,t[i])}}function lo(e,t){var n;if(jr(e))return Ar(e,"__ob__")&&e.__ob__ instanceof ao?n=e.__ob__:(Array.isArray(e)||Pr(e))&&Object.isExtensible(e)&&!e._isVue&&(n=new ao(e)),n&&t&&n.addVm(t),n}ao.prototype.walk=function(e){for(var t in e)this.convert(t,e[t])},ao.prototype.observeArray=function(e){for(var t=0,n=e.length;t<n;t++)lo(e[t])},ao.prototype.convert=function(e,t){!function(o,e,i){var a=new Zr,t=Object.getOwnPropertyDescriptor(o,e);if(t&&!1===t.configurable)return;var s=t&&t.get,n=t&&t.set,c=lo(i);Object.defineProperty(o,e,{enumerable:!0,configurable:!0,get:function(){var e=s?s.call(o):i;if(Zr.target&&(a.depend(),c&&c.dep.depend(),Array.isArray(e)))for(var t=void 0,n=0,r=e.length;n<r;n++)(t=e[n])&&t.__ob__&&t.__ob__.dep.depend();return e},set:function(e){var t=s?s.call(o):i;e!==t&&(n?n.call(o,e):i=e,c=lo(e),a.notify())}})}(this.value,e,t)},ao.prototype.addVm=function(e){(this.vms||(this.vms=[])).push(e)},ao.prototype.removeVm=function(e){Er(this.vms,e)};var uo=["$index","$value","$event"];function fo(t,n){(-1<uo.indexOf(n)||!Fr(n))&&Object.defineProperty(t,n,{configurable:!0,enumerable:!0,get:function(){return t._data[n]},set:function(e){t._data[n]=e}})}function po(e){var t=e._data;Pr(t)||(t={});for(var n=Object.keys(t),r=n.length;r--;)fo(e,n[r]);lo(t,e)}function ho(){}function vo(e){var t=e._computed;if(t)for(var n in t){var r=t[n],o={enumerable:!0,configurable:!0};o.set="function"==typeof r?(o.get=mo(r,e),ho):(o.get=r.get?!1!==r.cache?mo(r.get,e):Ir(r.get,e):ho,r.set?Ir(r.set,e):ho),Object.defineProperty(e,n,o)}}function mo(e,t){var n=new to(t,e,null,{lazy:!0});return function(){return n.dirty&&n.evaluate(),Zr.target&&n.depend(),n.value}}var yo={nativeComponentMap:{text:!0,image:!0,container:!0,slider:{type:"slider",append:"tree"},cell:{type:"cell",append:"tree"}}},go=yo.nativeComponentMap,_o={attr:"setAttr",style:"setStyle",event:"addEvent"};function bo(e,t,n){var r,o,i,a,s,c;So(e,t,n.id,e),r=e,o=t,i=n.attr,Co(r,o,"attr",i),function(e,t,n){if("function"!=typeof n&&!Array.isArray(n))return;if(Array.isArray(n)&&!n.length)return t.setClassStyle({});var r=e._options&&e._options.style||{};if("function"==typeof n){var o=Eo(e,n,function(e){Oo(t,r,e)});Oo(t,r,o)}else Oo(t,r,n)}(e,t,n.classList),a=e,s=t,c=n.style,Co(a,s,"style",c),function(e,t,n){if(!n)return;var r=Object.keys(n),o=r.length;for(;o--;){var i=r[o],a=n[i];"string"==typeof a&&((a=e[a])||console.warn('[JS Framework] The event handler "'+a+'" is not defined.')),s=e,c=i,l=a,t.addEvent(c,Ir(l,s))}var s,c,l}(e,t,n.events)}function wo(e,t,n,r){void 0===r&&(r={}),function(e,t,n){var r=t._options&&t._options.style||{};if(!n._rootEl)return;var o="@originalRootEl";function i(e,t){"array"===Vr(e)&&e.unshift(t)}if(r[o]=n._rootEl.classStyle,"function"==typeof e){var a=Eo(t,e,function(e){i(e,o),Oo(n._rootEl,r,e)});i(a,o),Oo(n._rootEl,r,a)}else null!=e&&(i(e,o),Oo(n._rootEl,r,e))}(n.classList,e,t),function(r,o,i){var e=function(t){var e=r[t];if("function"==typeof e){var n=Eo(o,e,function(e){i._rootEl&&i._rootEl.setStyle(t,e)});i._rootEl.setStyle(t,n)}else i._rootEl&&i._rootEl.setStyle(t,e)};for(var t in r)e(t)}(n.style,e,t),r.children?r.children[r.children.length-1]._vm=t:r._vm=t}function ko(r,o,i,a){if(r){var e=function(t){if(!o||o[t]){var e=r[t];if("function"==typeof e){var n=Eo(i,e,function(e){a[t]=e});a[t]=n}else a[t]=e}};for(var t in r)e(t)}}function So(t,e,n,r){var o=Object.create(null);if(Object.defineProperties(o,{vm:{value:r,writable:!1,configurable:!1},el:{get:function(){return e||r._rootEl},configurable:!1}}),"function"==typeof n){var i=n;((n=i.call(t))||0===n)&&(t._ids[n]=o),Eo(t,i,function(e){e&&(t._ids[e]=o)})}else n&&"string"==typeof n&&(t._ids[n]=o)}function Oo(e,n,r){"string"==typeof r&&(r=r.split(/\s+/)),r.forEach(function(e,t){r.splice.apply(r,[t,1].concat(e.split(/\s+/)))});for(var o={},t=r.length,i=function(e){var t=n[r[e]];t&&Object.keys(t).forEach(function(e){o[e]=t[e]})},a=0;a<t;a++)i(a);e.setClassStyle(o)}function Co(e,t,n,r){if(r)for(var o=Object.keys(r),i=o.length;i--;){var a=o[i],s=r[a];"function"==typeof s?xo(e,t,n,a,s):t[_o[n]](a,s)}}function xo(r,o,e,i,t){var a=_o[e],n=Eo(r,t,function(e){function t(){o[a](i,e)}var n=r&&r._app&&r._app.differ;n?n.append("element",o.depth||0,o.ref,t):t()});o[a](i,n)}function Eo(e,t,n){return e._static?t.call(e,e):new to(e,t,function(e,t){"object"!=typeof e&&e===t||n(e)}).value}function $o(e,t){var n=e._app.doc.createComment("start"),r=e._app.doc.createComment("end"),o=Ao++;if(t.element){var i=t.updateMark;i?(i.element&&(i=i.end),t.element.insertAfter(r,i),t.element.insertAfter(n,i),t.updateMark=r):(t.element.insertBefore(n,t.end),t.element.insertBefore(r,t.end)),t=t.element}else t.appendChild(n),t.appendChild(r);return{start:n,end:r,element:t,blockId:o}}var Ao=1;function Io(e,t,n){if(n.element){var r=n.end,o=n.updateMark;if(n.children&&n.children.push(t),o){var i=jo(e,t,o);return n.updateMark=t.element?t.end:t,i}if(!t.element)return n.element.insertBefore(t,r);n.element.insertBefore(t.start,r),n.element.insertBefore(t.end,r)}else{if(!t.element)return n.appendChild(t);n.appendChild(t.start),n.appendChild(t.end)}}function jo(e,t,n){return t.element?function(e,t){var n=t.parentNode;if(n){for(var r,o=e.start,i=[o];o&&o!==e.end;)o=o.nextSibling,i.push(o);var a=t;return i.every(function(e){return r=n.insertAfter(e,a),a=e,-1!==r}),r}}(t,n):function(e,t){var n=t.parentNode;if(n)return n.insertAfter(e,t)}(t,n)}function Mo(e,t,n){void 0===n&&(n=!1),t.element?function(e,t){void 0===t&&(t=!1);var n=[],r=e.start.nextSibling;for(;r&&r!==e.end;)n.push(r),r=r.nextSibling;t||To(e.start);n.forEach(function(e){To(e)}),t||To(e.end)}(t,n):To(t),t._vm&&t._vm.$emit("hook:destroyed")}function To(e){var t=e.parentNode;t&&t.removeChild(e)}function Po(e,t,n,r){if(-1!==(e._app||{}).lastSignal){if(t.attr&&t.attr.hasOwnProperty("static")&&(e._static=!0),c=t,Array.isArray(c))return i=t,a=r,s=$o(o=e,n),void i.forEach(function(e){Po(o,e,s,a)});var o,i,a,s,c,l,u,f;if(r=r||{},"content"===(l=t).type||"slot"===l.type)return console.debug('[JS Framework] compile "content" block by',t),void(e._content=$o(e,n));if(u=t,!r.hasOwnProperty("repeat")&&u.repeat)return console.debug('[JS Framework] compile "repeat" logic by',t),void("document"===n.type?console.warn("[JS Framework] The root element does't support `repeat` directive!"):function(e,t,n){var r=t.repeat,o="function"==typeof r,i=r.getter||r.expression||r;"function"!=typeof i&&(i=function(){return[]});var a=r.key||"$index",s=r.value||"$value",c=r.trackBy||t.trackBy||t.attr&&t.attr.trackBy,l=$o(e,n);l.children=[],l.data=[],l.vms=[],function(c,i,l,e){var u=l.vms,f=l.children,t=e.getter,p=e.trackBy,d=e.oldStyle,h=e.key,v=e.value;function m(e,t,n){var r;d?jr(r=e)?(r[h]=t,r.hasOwnProperty("INDEX")||Object.defineProperty(r,"INDEX",{value:function(){console.warn('[JS Framework] "INDEX" in repeat is deprecated, please use "$index" instead')}})):(console.warn("[JS Framework] Each list item must be an object in old-style repeat, please use `repeat={{v in list}}` instead."),(r={})[h]=t,r[v]=e):((r={})[h]=t,r[v]=e);var o=function(e,t){var n=Object.create(e);n._data=t,po(n),vo(n),(n._realParent=e)._static&&(n._static=e._static);return n}(n,r);u.push(o),Po(o,i,l,{repeat:e})}var n=No(c,l,t,"repeat",function(e){if(console.debug('[JS Framework] the "repeat" item has changed',e),l&&e){var r=f.slice(),o=u.slice(),t=l.data.slice(),i={},a={};e.forEach(function(e,t){var n=p?e[p]:d?e[h]:t;null!=n&&""!==n&&(i[n]=e)});var s=[];t.forEach(function(e,t){var n=p?e[p]:d?e[h]:t;i.hasOwnProperty(n)?(a[n]={item:e,index:t,key:n,target:r[t],vm:o[t]},s.push(e)):Mo(0,r[t])}),f.length=0,u.length=0,l.data=e.slice(),l.updateMark=l.start,e.forEach(function(e,t){var n=p?e[p]:d?e[h]:t,r=a[n];r?(r.item===s[0]?s.shift():(s.$remove(r.item),jo(0,r.target,l.updateMark)),f.push(r.target),u.push(r.vm),d?r.vm=e:r.vm[v]=e,r.vm[h]=t,l.updateMark=r.target):m(e,t,c)}),delete l.updateMark}});l.data=n.slice(0),n.forEach(function(e,t){m(e,t,c)})}(e,t,l,{getter:i,key:a,value:s,trackBy:c,oldStyle:o})}(e,t,n));if(f=t,!r.hasOwnProperty("shown")&&f.shown)return console.debug('[JS Framework] compile "if" logic by',t),void("document"===n.type?console.warn("[JS Framework] The root element does't support `if` directive!"):function(e,t,n,r){var o={shown:!0},i=$o(e,n);n.element&&n.children&&n.children.push(i);r.repeat&&(o.repeat=r.repeat);a=e,s=t,c=i,l=o,u=No(a,c,s.shown,"shown",function(e){console.debug('[JS Framework] the "if" item was changed',e),c&&!!c.display!=!!e&&(c.display=!!e,e?Po(a,s,c,l):Mo(0,c,!0))}),c.display=!!u,u&&Po(a,s,c,l);var a,s,c,l,u}(e,t,n,r));var p=r.type||t.type;if(d=r,"function"!=typeof p||d.hasOwnProperty("type")){var d,h,v,m,y,g,_,b,w=p,k=function(e,t,n){var r;e._app&&e._app.customComponentMap&&(r=e._app.customComponentMap[n]);e._options&&e._options.components&&(r=e._options.components[n]);t.component&&(r=r||{});return r}(e,t,w);if(k)return console.debug("[JS Framework] compile composed component by",t),v=k,m=t,y=n,g=w,_=r,b=new(h=e).constructor(g,v,h,y,void 0,{"hook:init":function(){h._static&&(this._static=h._static),So(h,null,m.id,this),this._externalBinding={parent:h,template:m}},"hook:created":function(){!function(e,t,n,r){n=n||{};var o=((t=t||{})._options||{}).props;Array.isArray(o)&&(o=o.reduce(function(e,t){return e[t]=!0,e},{})),ko(r,o,e,t),ko(n.attr,o,e,t)}(h,this,m,_.repeat)},"hook:ready":function(){this._content&&Fo(h,m,this._content)}}),void wo(h,b,m,y);console.debug("[JS Framework] compile native component by",t),function(e,t,n,r){var o;(function(e){var t=e.type,n=go[t];if("object"==typeof n)for(var r in n)if(null==e[r])e[r]=n[r];else if("object"===Vr(e[r])&&"object"===Vr(n[r]))for(var o in n[r])null==e[r][o]&&(e[r][o]=n[r][o])})(t),o="_documentElement"===n.ref?(console.debug("[JS Framework] compile to create body for "+r),a=r,e._app.doc.createBody(a)):(console.debug("[JS Framework] compile to create element for "+r),i=r,e._app.doc.createElement(i));var i;var a;if(!e._rootEl){e._rootEl=o;var s=e._externalBinding||{},c=s.template,l=s.parent;if(c&&c.events&&l&&o)for(var u in c.events){var f=l[c.events[u]];f&&o.addEvent(u,Ir(f,l))}}bo(e,o,t),t.attr&&t.attr.append&&(t.append=t.attr.append);t.append&&(o.attr=o.attr||{},o.attr.append=t.append);var p="tree"===t.append,d=e._app||{};-1===d.lastSignal||p||(console.debug("[JS Framework] compile to append single node for",o),d.lastSignal=Io(e,o,n));-1!==d.lastSignal&&Fo(e,t,o);-1!==d.lastSignal&&p&&(console.debug("[JS Framework] compile to append whole tree for",o),d.lastSignal=Io(e,o,n))}(e,t,n,w)}else!function(n,r,e,t,o){var i=Cr({type:t.call(n)},o),a=$o(n,e);e.element&&e.children&&e.children.push(a);Eo(n,t,function(e){var t=Cr({type:e},o);Mo(0,a,!0),Po(n,r,a,t)}),Po(n,r,a,i)}(e,t,n,p,r)}}function Fo(t,e,n){var r=t._app||{},o=e.children;o&&o.length&&o.every(function(e){return Po(t,e,n),-1!==r.lastSignal})}function No(e,t,n,r,o){var i=e&&e._app&&e._app.differ,a={},s=(t.element.depth||0)+1;return Eo(e,n,function(e){a.latestValue=e,i&&!a.recorded&&i.append(r,s,t.blockId,function(){var e=a.latestValue;o(e),a.recorded=!1,a.latestValue=void 0}),a.recorded=!0})}function Ro(e,t){if(t instanceof Ro)return t;this.timestamp=Date.now(),this.detail=t,this.type=e;var n=!1;this.stop=function(){n=!0},this.hasStopped=function(){return n}}function Do(e,t){var n=this,r=this._vmEvents[e];if(r){var o=new Ro(e,t);r.forEach(function(e){e.call(n,o)})}}function Vo(e,t){var n=new Ro(e,t);this.$emit(e,n),!n.hasStopped()&&this._parent&&this._parent.$dispatch&&this._parent.$dispatch(e,n)}function Lo(t,e){var n=new Ro(t,e);this.$emit(t,n),!n.hasStopped()&&this._childrenVms&&this._childrenVms.forEach(function(e){e.$broadcast(t,n)})}function Jo(e,t){if(e&&"function"==typeof t){var n=this._vmEvents,r=n[e]||[];r.push(t),n[e]=r,"hook:ready"===e&&this._ready&&this.$emit("hook:ready")}}function Wo(e,t){if(e){var n=this._vmEvents;if(t){var r=n[e];r&&r.$remove(t)}else delete n[e]}}var qo,Bo=["init","created","ready","destroyed"];function Uo(e,t,n,r,o,i){n=n||{},this._parent=n._realParent?n._realParent:n,this._app=n._app||{},n._childrenVms&&n._childrenVms.push(this),!t&&this._app.customComponentMap&&(t=this._app.customComponentMap[e]);var a,s,c,l,u=(t=t||{}).data||{};(this._options=t,this._methods=t.methods||{},this._computed=t.computed||{},this._css=t.style||{},this._ids={},this._vmEvents={},this._childrenVms=[],this._type=e,function(t,e){var n=t._options||{},r=n.events||{};for(var o in r)t.$on(o,r[o]);for(var i in e)t.$on(i,e[i]);Bo.forEach(function(e){t.$on("hook:"+e,n[e])})}(this,i),console.debug('[JS Framework] "init" lifecycle in Vm('+this._type+")"),this.$emit("hook:init"),this._inited=!0,this._data="function"==typeof u?u():u,o&&Cr(this._data,o),(a=this)._watchers=[],po(a),vo(a),function(e){var t=e._methods;if(t)for(var n in t)e[n]=t[n]}(a),console.debug('[JS Framework] "created" lifecycle in Vm('+this._type+")"),this.$emit("hook:created"),this._created=!0,t.methods&&t.methods.ready&&(console.warn('"exports.methods.ready" is deprecated, please use "exports.created" instead'),t.methods.ready.call(this)),this._app.doc)&&(this._parentEl=r||this._app.doc.documentElement,c=(s=this)._options||{},l=c.template||{},c.replace?l.children&&1===l.children.length?Po(s,l.children[0],s._parentEl):Po(s,l.children,s._parentEl):Po(s,l,s._parentEl),console.debug('[JS Framework] "ready" lifecycle in Vm('+s._type+")"),s.$emit("hook:ready"),s._ready=!0)}(qo=Uo.prototype).$emit=Do,qo.$dispatch=Vo,qo.$broadcast=Lo,qo.$on=Jo,qo.$off=Wo,Uo.prototype.$watch=function(e,t){Eo(this,e,t)},Uo.set=function e(t,n,r){if(Array.isArray(t))return t.splice(n,1,r);if(Ar(t,n))t[n]=r;else if(t._isVue)e(t._data,n,r);else{var o=t.__ob__;if(o){if(o.convert(n,r),o.dep.notify(),o.vms)for(var i=o.vms.length;i--;)fo(o.vms[i],n);return r}t[n]=r}},Uo.delete=function(e,t){if(Ar(e,t)){delete e[t];var n=e.__ob__;if(n){if(n.dep.notify(),n.vms)for(var r=n.vms.length;r--;)o=n.vms[r],Fr(i=t)||delete o[i]}else e._isVue&&delete e._data[t]}var o,i};var zo={};function Ho(n,r){var e=function(e){var t=zo[e];t||(t={},zo[e]=t),n[e].forEach(function(e){"string"==typeof e&&(e={name:e}),t[e.name]&&!r||(t[e.name]=e)})};for(var t in n)e(t)}function Go(e,t){return e.customComponentMap[t]}function Xo(e,t,n){var r=e.customComponentMap;r[t]?console.error("[JS Framework] define a component("+t+") that already exists"):r[t]=n}var Ko=n(function(e,r){var f;r=e.exports=H,"object"==typeof process&&process.env,f=function(){},r.SEMVER_SPEC_VERSION="2.0.0";var o=256,i=Number.MAX_SAFE_INTEGER||9007199254740991,c=r.re=[],t=r.src=[],n=0,a=n++;t[a]="0|[1-9]\\d*";var s=n++;t[s]="[0-9]+";var l=n++;t[l]="\\d*[a-zA-Z-][a-zA-Z0-9-]*";var u=n++;t[u]="("+t[a]+")\\.("+t[a]+")\\.("+t[a]+")";var p=n++;t[p]="("+t[s]+")\\.("+t[s]+")\\.("+t[s]+")";var d=n++;t[d]="(?:"+t[a]+"|"+t[l]+")";var h=n++;t[h]="(?:"+t[s]+"|"+t[l]+")";var v=n++;t[v]="(?:-("+t[d]+"(?:\\."+t[d]+")*))";var m=n++;t[m]="(?:-?("+t[h]+"(?:\\."+t[h]+")*))";var y=n++;t[y]="[0-9A-Za-z-]+";var g=n++;t[g]="(?:\\+("+t[y]+"(?:\\."+t[y]+")*))";var _=n++,b="v?"+t[u]+t[v]+"?"+t[g]+"?";t[_]="^"+b+"$";var w="[v=\\s]*"+t[p]+t[m]+"?"+t[g]+"?",k=n++;t[k]="^"+w+"$";var S=n++;t[S]="((?:<|>)?=?)";var O=n++;t[O]=t[s]+"|x|X|\\*";var C=n++;t[C]=t[a]+"|x|X|\\*";var x=n++;t[x]="[v=\\s]*("+t[C]+")(?:\\.("+t[C]+")(?:\\.("+t[C]+")(?:"+t[v]+")?"+t[g]+"?)?)?";var E=n++;t[E]="[v=\\s]*("+t[O]+")(?:\\.("+t[O]+")(?:\\.("+t[O]+")(?:"+t[m]+")?"+t[g]+"?)?)?";var $=n++;t[$]="^"+t[S]+"\\s*"+t[x]+"$";var A=n++;t[A]="^"+t[S]+"\\s*"+t[E]+"$";var I=n++;t[I]="(?:^|[^\\d])(\\d{1,16})(?:\\.(\\d{1,16}))?(?:\\.(\\d{1,16}))?(?:$|[^\\d])";var j=n++;t[j]="(?:~>?)";var M=n++;t[M]="(\\s*)"+t[j]+"\\s+",c[M]=new RegExp(t[M],"g");var T=n++;t[T]="^"+t[j]+t[x]+"$";var P=n++;t[P]="^"+t[j]+t[E]+"$";var F=n++;t[F]="(?:\\^)";var N=n++;t[N]="(\\s*)"+t[F]+"\\s+",c[N]=new RegExp(t[N],"g");var R=n++;t[R]="^"+t[F]+t[x]+"$";var D=n++;t[D]="^"+t[F]+t[E]+"$";var V=n++;t[V]="^"+t[S]+"\\s*("+w+")$|^$";var L=n++;t[L]="^"+t[S]+"\\s*("+b+")$|^$";var J=n++;t[J]="(\\s*)"+t[S]+"\\s*("+w+"|"+t[x]+")",c[J]=new RegExp(t[J],"g");var W=n++;t[W]="^\\s*("+t[x]+")\\s+-\\s+("+t[x]+")\\s*$";var q=n++;t[q]="^\\s*("+t[E]+")\\s+-\\s+("+t[E]+")\\s*$";var B=n++;t[B]="(<|>)?=?\\s*\\*";for(var U=0;U<35;U++)f(U,t[U]),c[U]||(c[U]=new RegExp(t[U]));function z(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof H)return e;if("string"!=typeof e)return null;if(e.length>o)return null;if(!(t.loose?c[k]:c[_]).test(e))return null;try{return new H(e,t)}catch(e){return null}}function H(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof H){if(e.loose===t.loose)return e;e=e.version}else if("string"!=typeof e)throw new TypeError("Invalid Version: "+e);if(e.length>o)throw new TypeError("version is longer than "+o+" characters");if(!(this instanceof H))return new H(e,t);f("SemVer",e,t),this.options=t,this.loose=!!t.loose;var n=e.trim().match(t.loose?c[k]:c[_]);if(!n)throw new TypeError("Invalid Version: "+e);if(this.raw=e,this.major=+n[1],this.minor=+n[2],this.patch=+n[3],this.major>i||this.major<0)throw new TypeError("Invalid major version");if(this.minor>i||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>i||this.patch<0)throw new TypeError("Invalid patch version");n[4]?this.prerelease=n[4].split(".").map(function(e){if(/^[0-9]+$/.test(e)){var t=+e;if(0<=t&&t<i)return t}return e}):this.prerelease=[],this.build=n[5]?n[5].split("."):[],this.format()}r.parse=z,r.valid=function(e,t){var n=z(e,t);return n?n.version:null},r.clean=function(e,t){var n=z(e.trim().replace(/^[=v]+/,""),t);return n?n.version:null},(r.SemVer=H).prototype.format=function(){return this.version=this.major+"."+this.minor+"."+this.patch,this.prerelease.length&&(this.version+="-"+this.prerelease.join(".")),this.version},H.prototype.toString=function(){return this.version},H.prototype.compare=function(e){return f("SemVer.compare",this.version,this.options,e),e instanceof H||(e=new H(e,this.options)),this.compareMain(e)||this.comparePre(e)},H.prototype.compareMain=function(e){return e instanceof H||(e=new H(e,this.options)),X(this.major,e.major)||X(this.minor,e.minor)||X(this.patch,e.patch)},H.prototype.comparePre=function(e){if(e instanceof H||(e=new H(e,this.options)),this.prerelease.length&&!e.prerelease.length)return-1;if(!this.prerelease.length&&e.prerelease.length)return 1;if(!this.prerelease.length&&!e.prerelease.length)return 0;var t=0;do{var n=this.prerelease[t],r=e.prerelease[t];if(f("prerelease compare",t,n,r),void 0===n&&void 0===r)return 0;if(void 0===r)return 1;if(void 0===n)return-1;if(n!==r)return X(n,r)}while(++t)},H.prototype.inc=function(e,t){switch(e){case"premajor":this.prerelease.length=0,this.patch=0,this.minor=0,this.major++,this.inc("pre",t);break;case"preminor":this.prerelease.length=0,this.patch=0,this.minor++,this.inc("pre",t);break;case"prepatch":this.prerelease.length=0,this.inc("patch",t),this.inc("pre",t);break;case"prerelease":0===this.prerelease.length&&this.inc("patch",t),this.inc("pre",t);break;case"major":0===this.minor&&0===this.patch&&0!==this.prerelease.length||this.major++,this.minor=0,this.patch=0,this.prerelease=[];break;case"minor":0===this.patch&&0!==this.prerelease.length||this.minor++,this.patch=0,this.prerelease=[];break;case"patch":0===this.prerelease.length&&this.patch++,this.prerelease=[];break;case"pre":if(0===this.prerelease.length)this.prerelease=[0];else{for(var n=this.prerelease.length;0<=--n;)"number"==typeof this.prerelease[n]&&(this.prerelease[n]++,n=-2);-1===n&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error("invalid increment argument: "+e)}return this.format(),this.raw=this.version,this},r.inc=function(e,t,n,r){"string"==typeof n&&(r=n,n=void 0);try{return new H(e,n).inc(t,r).version}catch(e){return null}},r.diff=function(e,t){{if(Q(e,t))return null;var n=z(e),r=z(t);if(n.prerelease.length||r.prerelease.length){for(var o in n)if(("major"===o||"minor"===o||"patch"===o)&&n[o]!==r[o])return"pre"+o;return"prerelease"}for(var o in n)if(("major"===o||"minor"===o||"patch"===o)&&n[o]!==r[o])return o}},r.compareIdentifiers=X;var G=/^[0-9]+$/;function X(e,t){var n=G.test(e),r=G.test(t);return n&&r&&(e=+e,t=+t),n&&!r?-1:r&&!n?1:e<t?-1:t<e?1:0}function K(e,t,n){return new H(e,n).compare(new H(t,n))}function Z(e,t,n){return 0<K(e,t,n)}function Y(e,t,n){return K(e,t,n)<0}function Q(e,t,n){return 0===K(e,t,n)}function ee(e,t,n){return 0!==K(e,t,n)}function te(e,t,n){return 0<=K(e,t,n)}function ne(e,t,n){return K(e,t,n)<=0}function re(e,t,n,r){var o;switch(t){case"===":"object"==typeof e&&(e=e.version),"object"==typeof n&&(n=n.version),o=e===n;break;case"!==":"object"==typeof e&&(e=e.version),"object"==typeof n&&(n=n.version),o=e!==n;break;case"":case"=":case"==":o=Q(e,n,r);break;case"!=":o=ee(e,n,r);break;case">":o=Z(e,n,r);break;case">=":o=te(e,n,r);break;case"<":o=Y(e,n,r);break;case"<=":o=ne(e,n,r);break;default:throw new TypeError("Invalid operator: "+t)}return o}function oe(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof oe){if(e.loose===!!t.loose)return e;e=e.value}if(!(this instanceof oe))return new oe(e,t);f("comparator",e,t),this.options=t,this.loose=!!t.loose,this.parse(e),this.semver===ie?this.value="":this.value=this.operator+this.semver.version,f("comp",this)}r.rcompareIdentifiers=function(e,t){return X(t,e)},r.major=function(e,t){return new H(e,t).major},r.minor=function(e,t){return new H(e,t).minor},r.patch=function(e,t){return new H(e,t).patch},r.compare=K,r.compareLoose=function(e,t){return K(e,t,!0)},r.rcompare=function(e,t,n){return K(t,e,n)},r.sort=function(e,n){return e.sort(function(e,t){return r.compare(e,t,n)})},r.rsort=function(e,n){return e.sort(function(e,t){return r.rcompare(e,t,n)})},r.gt=Z,r.lt=Y,r.eq=Q,r.neq=ee,r.gte=te,r.lte=ne,r.cmp=re,r.Comparator=oe;var ie={};function ae(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof ae)return e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease?e:new ae(e.raw,t);if(e instanceof oe)return new ae(e.value,t);if(!(this instanceof ae))return new ae(e,t);if(this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map(function(e){return this.parseRange(e.trim())},this).filter(function(e){return e.length}),!this.set.length)throw new TypeError("Invalid SemVer Range: "+e);this.format()}function se(e){return!e||"x"===e.toLowerCase()||"*"===e}function ce(e,t,n,r,o,i,a,s,c,l,u,f,p){return((t=se(n)?"":se(r)?">="+n+".0.0":se(o)?">="+n+"."+r+".0":">="+t)+" "+(s=se(c)?"":se(l)?"<"+(+c+1)+".0.0":se(u)?"<"+c+"."+(+l+1)+".0":f?"<="+c+"."+l+"."+u+"-"+f:"<="+s)).trim()}function le(e,t,n){for(var r=0;r<e.length;r++)if(!e[r].test(t))return!1;if(n||(n={}),!t.prerelease.length||n.includePrerelease)return!0;for(r=0;r<e.length;r++)if(f(e[r].semver),e[r].semver!==ie&&0<e[r].semver.prerelease.length){var o=e[r].semver;if(o.major===t.major&&o.minor===t.minor&&o.patch===t.patch)return!0}return!1}function ue(e,t,n){try{t=new ae(t,n)}catch(e){return!1}return t.test(e)}function fe(e,t,n,r){var o,i,a,s,c;switch(e=new H(e,r),t=new ae(t,r),n){case">":o=Z,i=ne,a=Y,s=">",c=">=";break;case"<":o=Y,i=te,a=Z,s="<",c="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(ue(e,t,r))return!1;for(var l=0;l<t.set.length;++l){var u=t.set[l],f=null,p=null;if(u.forEach(function(e){e.semver===ie&&(e=new oe(">=0.0.0")),f=f||e,p=p||e,o(e.semver,f.semver,r)?f=e:a(e.semver,p.semver,r)&&(p=e)}),f.operator===s||f.operator===c)return!1;if((!p.operator||p.operator===s)&&i(e,p.semver))return!1;if(p.operator===c&&a(e,p.semver))return!1}return!0}oe.prototype.parse=function(e){var t=this.options.loose?c[V]:c[L],n=e.match(t);if(!n)throw new TypeError("Invalid comparator: "+e);this.operator=n[1],"="===this.operator&&(this.operator=""),n[2]?this.semver=new H(n[2],this.options.loose):this.semver=ie},oe.prototype.toString=function(){return this.value},oe.prototype.test=function(e){return f("Comparator.test",e,this.options.loose),this.semver===ie||("string"==typeof e&&(e=new H(e,this.options)),re(e,this.operator,this.semver,this.options))},oe.prototype.intersects=function(e,t){if(!(e instanceof oe))throw new TypeError("a Comparator is required");var n;if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),""===this.operator)return n=new ae(e.value,t),ue(this.value,n,t);if(""===e.operator)return n=new ae(this.value,t),ue(e.semver,n,t);var r=!(">="!==this.operator&&">"!==this.operator||">="!==e.operator&&">"!==e.operator),o=!("<="!==this.operator&&"<"!==this.operator||"<="!==e.operator&&"<"!==e.operator),i=this.semver.version===e.semver.version,a=!(">="!==this.operator&&"<="!==this.operator||">="!==e.operator&&"<="!==e.operator),s=re(this.semver,"<",e.semver,t)&&(">="===this.operator||">"===this.operator)&&("<="===e.operator||"<"===e.operator),c=re(this.semver,">",e.semver,t)&&("<="===this.operator||"<"===this.operator)&&(">="===e.operator||">"===e.operator);return r||o||i&&a||s||c},(r.Range=ae).prototype.format=function(){return this.range=this.set.map(function(e){return e.join(" ").trim()}).join("||").trim(),this.range},ae.prototype.toString=function(){return this.range},ae.prototype.parseRange=function(e){var t=this.options.loose;e=e.trim();var n=t?c[q]:c[W];e=e.replace(n,ce),f("hyphen replace",e),e=e.replace(c[J],"$1$2$3"),f("comparator trim",e,c[J]),e=(e=(e=e.replace(c[M],"$1~")).replace(c[N],"$1^")).split(/\s+/).join(" ");var r=t?c[V]:c[L],o=e.split(" ").map(function(e){return t=e,n=this.options,f("comp",t,n),s=n,t=t.trim().split(/\s+/).map(function(e){return function(a,e){f("caret",a,e),e&&"object"==typeof e||(e={loose:!!e,includePrerelease:!1});var t=e.loose?c[D]:c[R];return a.replace(t,function(e,t,n,r,o){var i;return f("caret",a,e,t,n,r,o),i=se(t)?"":se(n)?">="+t+".0.0 <"+(+t+1)+".0.0":se(r)?"0"===t?">="+t+"."+n+".0 <"+t+"."+(+n+1)+".0":">="+t+"."+n+".0 <"+(+t+1)+".0.0":o?(f("replaceCaret pr",o),"-"!==o.charAt(0)&&(o="-"+o),"0"===t?"0"===n?">="+t+"."+n+"."+r+o+" <"+t+"."+n+"."+(+r+1):">="+t+"."+n+"."+r+o+" <"+t+"."+(+n+1)+".0":">="+t+"."+n+"."+r+o+" <"+(+t+1)+".0.0"):(f("no pr"),"0"===t?"0"===n?">="+t+"."+n+"."+r+" <"+t+"."+n+"."+(+r+1):">="+t+"."+n+"."+r+" <"+t+"."+(+n+1)+".0":">="+t+"."+n+"."+r+" <"+(+t+1)+".0.0"),f("caret return",i),i})}(e,s)}).join(" "),f("caret",t),a=n,t=t.trim().split(/\s+/).map(function(e){return function(a,e){e&&"object"==typeof e||(e={loose:!!e,includePrerelease:!1});var t=e.loose?c[P]:c[T];return a.replace(t,function(e,t,n,r,o){var i;return f("tilde",a,e,t,n,r,o),i=se(t)?"":se(n)?">="+t+".0.0 <"+(+t+1)+".0.0":se(r)?">="+t+"."+n+".0 <"+t+"."+(+n+1)+".0":o?(f("replaceTilde pr",o),"-"!==o.charAt(0)&&(o="-"+o),">="+t+"."+n+"."+r+o+" <"+t+"."+(+n+1)+".0"):">="+t+"."+n+"."+r+" <"+t+"."+(+n+1)+".0",f("tilde return",i),i})}(e,a)}).join(" "),f("tildes",t),f("replaceXRanges",o=t,i=n),t=o.split(/\s+/).map(function(e){return function(u,e){u=u.trim(),e&&"object"==typeof e||(e={loose:!!e,includePrerelease:!1});var t=e.loose?c[A]:c[$];return u.replace(t,function(e,t,n,r,o,i){f("xRange",u,e,t,n,r,o,i);var a=se(n),s=a||se(r),c=s||se(o),l=c;return"="===t&&l&&(t=""),a?e=">"===t||"<"===t?"<0.0.0":"*":t&&l?(s&&(r=0),c&&(o=0),">"===t?(t=">=",s?(n=+n+1,o=r=0):c&&(r=+r+1,o=0)):"<="===t&&(t="<",s?n=+n+1:r=+r+1),e=t+n+"."+r+"."+o):s?e=">="+n+".0.0 <"+(+n+1)+".0.0":c&&(e=">="+n+"."+r+".0 <"+n+"."+(+r+1)+".0"),f("xRange return",e),e})}(e,i)}).join(" "),f("xrange",t),f("replaceStars",r=t,n),t=r.trim().replace(c[B],""),f("stars",t),t;var t,n,r,o,i,a,s},this).join(" ").split(/\s+/);return this.options.loose&&(o=o.filter(function(e){return!!e.match(r)})),o=o.map(function(e){return new oe(e,this.options)},this)},ae.prototype.intersects=function(n,r){if(!(n instanceof ae))throw new TypeError("a Range is required");return this.set.some(function(e){return e.every(function(t){return n.set.some(function(e){return e.every(function(e){return t.intersects(e,r)})})})})},r.toComparators=function(e,t){return new ae(e,t).set.map(function(e){return e.map(function(e){return e.value}).join(" ").trim().split(" ")})},ae.prototype.test=function(e){if(!e)return!1;"string"==typeof e&&(e=new H(e,this.options));for(var t=0;t<this.set.length;t++)if(le(this.set[t],e,this.options))return!0;return!1},r.satisfies=ue,r.maxSatisfying=function(e,t,n){var r=null,o=null;try{var i=new ae(t,n)}catch(e){return null}return e.forEach(function(e){i.test(e)&&(r&&-1!==o.compare(e)||(o=new H(r=e,n)))}),r},r.minSatisfying=function(e,t,n){var r=null,o=null;try{var i=new ae(t,n)}catch(e){return null}return e.forEach(function(e){i.test(e)&&(r&&1!==o.compare(e)||(o=new H(r=e,n)))}),r},r.validRange=function(e,t){try{return new ae(e,t).range||"*"}catch(e){return null}},r.ltr=function(e,t,n){return fe(e,t,"<",n)},r.gtr=function(e,t,n){return fe(e,t,">",n)},r.outside=fe,r.prerelease=function(e,t){var n=z(e,t);return n&&n.prerelease.length?n.prerelease:null},r.intersects=function(e,t,n){return e=new ae(e,n),t=new ae(t,n),e.intersects(t)},r.coerce=function(e){if(e instanceof H)return e;if("string"!=typeof e)return null;var t=e.match(c[I]);return null!=t?z((t[1]||"0")+"."+(t[2]||"0")+"."+(t[3]||"0")):null}});Ko.SEMVER_SPEC_VERSION,Ko.re,Ko.src,Ko.parse,Ko.valid,Ko.clean,Ko.SemVer,Ko.inc,Ko.diff,Ko.compareIdentifiers,Ko.rcompareIdentifiers,Ko.major,Ko.minor,Ko.patch,Ko.compare,Ko.compareLoose,Ko.rcompare,Ko.sort,Ko.rsort,Ko.gt,Ko.lt,Ko.eq,Ko.neq,Ko.gte,Ko.lte,Ko.cmp,Ko.Comparator,Ko.Range,Ko.toComparators,Ko.satisfies,Ko.maxSatisfying,Ko.minSatisfying,Ko.validRange,Ko.ltr,Ko.gtr,Ko.outside,Ko.prerelease,Ko.intersects,Ko.coerce;function Zo(e){if(Ko.valid(e))return e;for(var t=(e="string"==typeof e?e:"").split("."),n=0,r=[];n<3;){var o="string"==typeof t[n]&&t[n]?t[n]:"0";r.push(o),n++}return r.join(".")}function Yo(e,t,n){var r={isDowngrade:!0,errorType:1,code:1e3},o=e.toLowerCase();return r.errorMessage="Downgrade["+e+"] :: deviceInfo "+t+" matched criteria "+n,0<=o.indexOf("osversion")?r.code=1001:0<=o.indexOf("appversion")?r.code=1002:0<=o.indexOf("weexversion")?r.code=1003:0<=o.indexOf("devicemodel")&&(r.code=1004),r}function Qo(e,t,n,r){var o;if(console.debug("[JS Framework] bootstrap for "+t),Br(t))o=Gr(t);else{if(!Hr(t))return new Error("Wrong component name: "+t);if(!Go(e,o=Xr(t)))return new Error("It's not a component: "+t)}if("string"==typeof(n=Pr(n)?n:{}).transformerVersion&&"string"==typeof global.transformerVersion&&!Ko.satisfies(n.transformerVersion,global.transformerVersion))return new Error("JS Bundle version: "+n.transformerVersion+" not compatible with "+global.transformerVersion);var i=function(e,t){t=Pr(t=t||global.WXEnvironment)?t:{};var n={isDowngrade:!1};if("function"===Vr(e)){var r=e.call(this,t,{semver:Ko,normalizeVersion:Zo});n=(r=!!r)?Yo("custom","","custom params"):n}else{var o=(e=Pr(e)?e:{})[(t.platform||"unknow").toLowerCase()]||{};for(var i in t){var a=i,s=a.toLowerCase(),c=t[i],l=0<=s.indexOf("version"),u=0<=s.indexOf("devicemodel"),f=o[i];if(f&&l){var p=Zo(f),d=Zo(t[i]);if(Ko.satisfies(d,p)){n=Yo(a,c,f);break}}else if(u&&0<=("array"===Vr(f)?f:[f]).indexOf(c)){n=Yo(a,c,f);break}}}return n}(n.downgrade);if(i.isDowngrade)return e.callTasks([{module:"instanceWrap",method:"error",args:[i.errorType,i.code,i.errorMessage]}]),new Error("Downgrade["+i.code+"]: "+i.errorMessage);n.viewport&&function(e,t){if(void 0===t&&(t={}),e&&e.callTasks)e.callTasks([{module:"meta",method:"setViewport",args:[t]}])}(e,n.viewport),e.vm=new Uo(o,null,{_app:e},null,r)}var ei=function(o,e){for(var t,n,r,i=[],a=arguments.length-2;0<a--;)i[a]=arguments[a+2];if(console.debug("[JS Framework] define a component "+e),"function"==typeof(r=1<i.length?i[1]:i[0])&&(n=r,r=null),n){var s={exports:{}};n(function(e){if(Br(e)){var t=Gr(e);return Go(o,t)}if(Ur(e)){var n=Gr(e);return o.requireModule(n)}if(zr(e)||Hr(e)){var r=Xr(e);return o.commonModules[r]}},s.exports,s),r=s.exports}if(Br(e)){var c=Gr(e);Xo(o,c,r)}else if(Ur(e)){Ho(((t={})[Gr(e)]=r,t))}else if(zr(e)){var l=Xr(e);o.commonModules[l]=r}else if(Hr(e)){var u=Xr(e);r.template||r.style||r.methods?Xo(o,u,r):o.commonModules[u]=r}};function ti(e){console.debug("[JS Framework] Destory an instance("+e.id+")"),e.vm&&function e(t){delete t._app;delete t._computed;delete t._css;delete t._data;delete t._ids;delete t._methods;delete t._options;delete t._parent;delete t._parentEl;delete t._rootEl;if(t._watchers){for(var n=t._watchers.length;n--;)t._watchers[n].teardown();delete t._watchers}if(t._childrenVms){for(var r=t._childrenVms.length;r--;)e(t._childrenVms[r]);delete t._childrenVms}console.debug('[JS Framework] "destroyed" lifecycle in Vm('+t._type+")");t.$emit("hook:destroyed");delete t._type;delete t._vmEvents}(e.vm),e.id="",e.options=null,e.blocks=null,e.vm=null,e.doc.taskCenter.destroyCallback(),e.doc.destroy(),e.doc=null,e.customComponentMap=null,e.commonModules=null}function ni(e){e.differ.flush()}function ri(r,e,o,t){var i;console.debug("[JS Framework] Intialize an instance with:\n",o);var n,a=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return ei.apply(void 0,[r].concat(e))},s=function(e,t,n){i=Qo(r,e,t,n||o),ni(r),r.doc.listener.createFinish(),console.debug("[JS Framework] After intialized an instance("+r.id+")")},c=Uo,l=r.doc,u=function(e){return r.requireModule(Gr(e))},f={config:r.options,define:a,bootstrap:s,requireModule:u,document:l,Vm:c};Object.freeze(f),"function"==typeof e?n=e.toString().substr(12):e&&(n=e.toString()),n='(function(global){\n\n"use strict";\n\n '+n+" \n\n})(Object.create(this))";var p=global.WXEnvironment,d={};if(p&&"Web"!==p.platform){var h=r.requireModule("timer");Object.assign(d,{setTimeout:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return h.setTimeout(function(){e[0].apply(e,e.slice(2))},e[1]),r.doc.taskCenter.callbackManager.lastCallbackId.toString()},setInterval:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return h.setInterval(function(){e[0].apply(e,e.slice(2))},e[1]),r.doc.taskCenter.callbackManager.lastCallbackId.toString()},clearTimeout:function(e){h.clearTimeout(e)},clearInterval:function(e){h.clearInterval(e)}})}var v=Object.assign({define:a,require:function(t){return function(e){i=Qo(r,t,{},e)}},bootstrap:s,register:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return function(e,t,n){console.warn("[JS Framework] Register is deprecated, please install lastest transformer."),Xo(e,t,n)}.apply(void 0,[r].concat(e))},render:function(e,t){i=Qo(r,e,{},t)},__weex_define__:a,__weex_bootstrap__:s,__weex_document__:l,__weex_require__:u,__weex_viewmodel__:c,weex:f},d,t);return function(e,t){if("function"!=typeof compileAndRunBundle)return!1;var n=void 0,r=!1,o="(function (",i=[],a=[];for(var s in e)i.push(s),a.push(e[s]);for(var c=0;c<i.length-1;++c)o+=i[c],o+=",";o+=i[i.length-1],o+=") {",o+=t,o+="} )";try{var l=e.weex||{},u=l.config||{};(n=compileAndRunBundle(o,u.bundleUrl,u.bundleDigest,u.codeCachePath))&&"function"==typeof n&&(n.apply(void 0,a),r=!0)}catch(e){console.error(e)}return r}(v,n)||function(e,t){var n=[],r=[];for(var o in e)n.push(o),r.push(e[o]);n.push(t),(new(Function.prototype.bind.apply(Function,[null].concat(n)))).apply(void 0,r)}(v,n),i}var oi=function(e){this.id=e,this.map=[],this.hooks=[]};function ii(e,t){var n=e[t];for(var r in n)n[r]()}function ai(e,t){this.id=e,this.options=t||{},this.vm=null,this.customComponentMap={},this.commonModules={},this.doc=new yo.Document(e,this.options.bundleUrl,null,yo.Listener),this.differ=new oi(e)}oi.prototype.isEmpty=function(){return 0===this.map.length},oi.prototype.append=function(e,t,n,r){var o=this;void 0===t&&(t=0),this.hasTimer||(this.hasTimer=!0,setTimeout(function(){o.hasTimer=!1,o.flush(!0)},0));var i=this.map;i[t]||(i[t]={});var a=i[t];a[e]||(a[e]={}),"element"===e?(a[e][n]||(a[e][n]=[]),a[e][n].push(r)):a[e][n]=r},oi.prototype.flush=function(e){var t=this.map.slice();this.map.length=0,t.forEach(function(e){ii(e,"repeat"),ii(e,"shown"),function(e,t){var n=e[t];for(var r in n){var o=n[r];o.forEach(function(e){e()})}}(e,"element")});var n=this.hooks.slice();this.hooks.length=0,n.forEach(function(e){e()}),this.isEmpty()||this.flush()},oi.prototype.then=function(e){this.hooks.push(e)},ai.prototype.requireModule=function(e){return function(r,o){var e=zo[o],t={},n=function(n){Object.defineProperty(t,n,{configurable:!0,enumerable:!0,get:function(){return function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return r.callTasks({module:o,method:n,args:e})}},set:function(e){if("function"==typeof e)return r.callTasks({module:o,method:n,args:[e]})}})};for(var i in e)n(i);return t}(this,e)},ai.prototype.updateActions=function(){return ni(this)},ai.prototype.callTasks=function(e){return t=this,"array"!==Vr(n=e)&&(n=[n]),n.forEach(function(e){r=t.doc.taskCenter.send("module",{module:e.module,method:e.method},e.args)}),r;var t,n,r},Object.freeze(ai),Object.freeze(ai.prototype);var si={};var ci=yo.nativeComponentMap;function li(e){"object"==typeof e&&function(e,t){var n=e.prototype;for(var r in t)n.hasOwnProperty(r)||(n[r]=t[r])}(Uo,e)}global.registerMethods=li;var ui={fireEvent:function(e){for(var t=[],n=arguments.length-1;0<n--;)t[n]=arguments[n+1];return function t(n,e,r,o,i){if(console.debug('[JS Framework] Fire a "'+r+'" event on an element('+e+") in instance("+n.id+")"),!Array.isArray(e)){var a=n.doc.getRef(e);if(a){var s=n.doc.fireEvent(a,r,o,i);return n.differ.flush(),n.doc.taskCenter.send("dom",{action:"updateFinish"},[]),s}return new Error('invalid element reference "'+e+'"')}e.some(function(e){return!1!==t(n,e,r,o)})}.apply(void 0,[si[e]].concat(t))},callback:function(e){for(var t=[],n=arguments.length-1;0<n--;)t[n]=arguments[n+1];return function(e,t,n,r){console.debug("[JS Framework] Invoke a callback("+t+") with",n,"in instance("+e.id+")");var o=e.doc.taskCenter.callback(t,n,r);return ni(e),e.doc.taskCenter.send("dom",{action:"updateFinish"},[]),o}.apply(void 0,[si[e]].concat(t))}};li(Or),Object.freeze(Uo);var fi=Object.freeze({registerComponents:function(e){Array.isArray(e)&&e.forEach(function(e){e&&("string"==typeof e?ci[e]=!0:"object"==typeof e&&"string"==typeof e.type&&(ci[e.type]=e))})},registerModules:function(e){"object"==typeof e&&Ho(e)},registerMethods:li,createInstance:function(e,t,n,r,o){var i=(o||{}).services;Qr();var a,s=si[e];return n=n||{},(a=s?new Error('invalid instance id "'+e+'"'):(s=new ai(e,n),ri(si[e]=s,t,r,i)))instanceof Error?a:s},init:function(e){yo.Document=e.Document,yo.Element=e.Element,yo.Comment=e.Comment,yo.sendTasks=e.sendTasks,yo.Listener=e.Listener},refreshInstance:function(e,t){var n=si[e];return n?function(e,t){console.debug("[JS Framework] Refresh with",t,"in instance["+e.id+"]");var n=e.vm;return n&&t?("function"==typeof n.refreshData?n.refreshData(t):Cr(n,t),e.differ.flush(),void e.doc.taskCenter.send("dom",{action:"refreshFinish"},[])):new Error('invalid data "'+t+'"')}(n,t):new Error('invalid instance id "'+e+'"')},destroyInstance:function(e){"function"==typeof markupState&&markupState(),Qr();var t=si[e];if(!t)return new Error('invalid instance id "'+e+'"');ti(t),delete si[e];var n=Math.round(e);return 0<n&&(n%18||"function"!=typeof notifyTrimMemory||notifyTrimMemory()),si},receiveTasks:function(r,e){if(si[r]&&Array.isArray(e)){var o=[];return e.forEach(function(e){var t=ui[e.method],n=[].concat(e.args);"function"==typeof t&&(n.unshift(r),o.push(t.apply(void 0,n)))}),o}return new Error('invalid instance id "'+r+'" or tasks')},getRoot:function(e){var t,n=si[e];return n?(t=(n.doc||{}).body||{}).toJSON?t.toJSON():{}:new Error('invalid instance id "'+e+'"')}}),pi={Vanilla:mr,Vue:Sr,Rax:e(n(function(e){e.exports=function(n){var r={};function o(e){if(r[e])return r[e].exports;var t=r[e]={i:e,l:!1,exports:{}};return n[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}return o.m=n,o.c=r,o.d=function(e,t,n){o.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:n})},o.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=0)}([function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.getInstance=r,t.init=function(e){c=e.Document,e.Element,e.Comment},t.createInstanceContext=function(e,t,n){var r=l[e],o=t.weex;{if(null!=r)throw new Error('Instance id "'+e+'" existed when create instance');var i=o.config.bundleUrl;i?i.split("//")[0]||(i="https:"+i):(console.error('Error: Must have bundleUrl option when createInstance, downgrade to "about:blank".'),i="about:blank");var a=new c(e,i);r=l[e]={document:a,instanceId:e,bundleUrl:i,__weex_data__:n,uid:0};var s={instanceId:e,bundleUrl:i,document:a,__weex_document__:a,__weex_options__:t,__weex_data__:n||{},callNative:function(){},__weex_config__:t};return s}},t.refreshInstance=function(e,t){var n=r(e).document;n.documentElement.fireEvent("refresh",{timestamp:Date.now(),data:t}),n.taskCenter.send("dom",{action:"refreshFinish"},[])},t.destroyInstance=function(e){var t=r(e),n=(t.bundleCode,t.document);n.documentElement.fireEvent("destory",{timestamp:Date.now()}),n.destroy&&n.destroy();n.taskCenter&&n.taskCenter.destroyCallback&&n.taskCenter.destroyCallback();delete l[e]};var c=void 0,l={};function r(e){var t=l[e];if(!t)throw new Error('Invalid instance id "'+e+'"');return t}t.default=t}])})),Weex:fi};var di,hi,vi,mi,yi=Object.freeze({$userTrack:function(e,t,n,r){console.error("[Upgrade Warning] $userTrack will be removed in the next version!"),console.error("[JS Framework] Vm#$userTrack is deprecated, please use \"require('@weex-module/userTrack').commit(type, name, comName, param)\" instead"),this._app.requireModule("userTrack").commit(e,t,n,r)},$sendMtop:function(e,t){console.error("[Upgrade Warning] $sendMtop will be removed in the next version!"),console.error("[JS Framework] Vm#$sendMtop is deprecated, please use \"require('@weex-module/stream').sendMtop(params, callback)\" instead"),"undefined"==typeof window?this._app.requireModule("windvane").call({class:"MtopWVPlugin",method:"send",data:e},t):this._app.requireModule("stream").sendMtop(e,t)},$callWindvane:function(e,t){console.error("[Upgrade Warning] $callWindvane will be removed in the next version!"),console.error("[JS Framework] Vm#$callWindvane is deprecated, please use \"require('@weex-module/windvane').call(params, callback)\" instead"),this._app.requireModule("windvane").call(e,t)},$setSpm:function(e,t){console.error("[Upgrade Warning] $setSpm will be removed in the next version!"),console.error("[JS Framework] Vm#$setSpm is deprecated, please use \"require('@weex-module/pageInfo').setSpm(a, b)\" instead"),this._app.requireModule("pageInfo").setSpm(e,t)},$getUserInfo:function(e){console.error("[Upgrade Warning] $getUserInfo will be removed in the next version!"),console.error("[JS Framework] Vm#$getUserInfo is deprecated, please use \"require('@weex-module/user').getUserInfo(callback)\" instead"),this._app.requireModule("user").getUserInfo(e)},$login:function(e){console.error("[Upgrade Warning] $login will be removed in the next version!"),console.error("[JS Framework] Vm#$login is deprecated, please use \"require('@weex-module/user').login(callback)\" instead"),this._app.requireModule("user").login(e)},$logout:function(e){console.error("[Upgrade Warning] $logout will be removed in the next version!"),console.error("[JS Framework] Vm#$logout is deprecated, please use \"require('@weex-module/user').logout(callback)\" instead"),this._app.requireModule("user").logout(e)}}),gi=n(function(e,t){console.log("Start windmill weex-vue-plugin (0.3.2) framework. Build at 2018-09-18 13:06"),e.exports=function(){"function"!=typeof Object.assign&&Object.defineProperty(Object,"assign",{writable:!0,enumerable:!1,configurable:!0,value:function(e,t){var n=arguments;if(null==e)throw new TypeError("Cannot convert undefined or null to object");for(var r=Object(e),o=1;o<arguments.length;o++){var i=n[o];if(null!=i)for(var a in i)Object.prototype.hasOwnProperty.call(i,a)&&(r[a]=i[a])}return r}});var t,i=(t=1e5,function(){var e=String(t);return t+=1,e});function s(t,n,e){void 0===e&&(e=!0);var r=void 0!==global?global:"undefined"!=typeof self?self:new Function("return this")();try{Object.defineProperty(r,t,{value:n,configurable:!0,enumerable:!0,writable:!e})}catch(e){r[t]=n}}function c(e){return Object.prototype.toString.call(e).slice(8,-1)}function l(e){return"Object"===c(e)}function o(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n]}function f(o,i){var a;return void 0===i&&(i=0),"function"!=typeof setTimeout||"function"!=typeof clearTimeout?(console.warn("[Warn] There is no timer API in the current context."),o):function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];var r=this;clearTimeout(a),a=setTimeout(function(){return o.apply(r,t)},i)}}var n=function(){},u={},a=["Android","iOS"];function r(e,t){return"object"==typeof process&&process&&process.env&&"test"===process.env.PURPOSE?"function"==typeof __test_logger__&&(n=__test_logger__,!0):(u.debugMode,!0)}function p(e,t){r()&&n("log",e)}function d(e,t){r()&&n("debug",e)}function h(e,t){r()&&n("warn",e)}function v(e,t){r()&&n("error",e)}function m(e){if(v(e),"test"!==process.env.PURPOSE)throw new Error(e)}n=function(e,t){var n,r="["+((n=e).charAt(0).toUpperCase()+n.slice(1))+"][wml-r] "+t;return u.isWeex&&-1<a.indexOf(u.platform)?console.log(r):console.error(r)};var y={network:["request","uploadFile"],miniApp:["setAppShareInfo","hideLauncherLoading","setWebViewTop","setWebViewBackgroundImage"],mtop:["request"],storage:["length","setItem","getItem","removeItem"],memoryStorage:["setItem","getItem"],tabBar:["show","hide"],navigator:["push","pop","openMessagePage","reloadPage","getBackStack","popToHome","navigateTo","redirectTo","switchTab"],user:["login","logout","info"],modal:["alert","confirm","toast","showLoading","hideLoading"],navigatorBar:["show","hide","setTitle","setRightItem","setStyle","setDrawer","setActionSheet","hasIndexBadge","scaleIndexBadge","resetIndexBadge","getHeight","openDrawer","isDrawerOpened","closeDrawer","setLeftItem","showMenu","hideMenu","getStatusBarHeight","setNavigationBar"],clipboard:["writeText","readText"],picker:["pick","pickDate","pickTime","chooseCity"],webSocket:["webSocket","send","close","onOpen","onMessage","onClose","onError"],calendar:["addEvent","checkEvent","removeEvent"],connection:["getType","getDownlinkMax","onChange"],screen:["setAlwaysOn","setBrightness","getScreenBrightness"],broadcast:["createChannel","postMessage","onMessage","close"],share:["doShare"],cookie:["read","write","getAllObjects"],audio:["load","play","pause","stop","setVolume","canPlayType"],wopc:["authLogin","checkAuthSession","doAuth","getSessionKey","setSessionKey"],WopcMtopPlugin:["request"],device:["onShake","vibrate"],keyboard:["hideKeyboard"],contact:["choosePhoneContact"],location:["getLocation"],alipay:["tradePay"],userTrack:["commit","commitut","commitEvent","customAdvance","pageAppear","pageDisappear","skipPage","updatePageUtparam","updateNextPageUtparam"],"nuvajs-exec":["exec"],aluWVJSBridge:["userIsLogin","refreshAlipayCookie"],TBDeviceInfo:["getUtdid"],actionSheet:["showActionSheet"],image:["chooseImage","previewImage","compressImage","getImageInfo","saveImage"],media:["startVoice","stopVoice"],audioRecord:["startRecord","stopRecord","cancelRecord"],audioPlayer:["playVoice","pauseVoice","stopVoice"],file:["saveFile","getFileInfo","getFileList","removeFile"],video:["chooseVideo","getVideoInfo"],phone:["makePhoneCall"],compass:["startCompass","stopCompass","onCompassChange"],tbsecurity:["secureToken"]};function g(o,e){var i=e||function(){for(var e,t=arguments,n=[],r=arguments.length;r--;)n[r]=t[r];return(e=o()).$call.apply(e,n)};return function(o){if(!o)return d("Require a universal module proxy."),{call:i};var e=y[o];if(Array.isArray(e)){d('Require the "'+o+'" module.');var t={};return e.forEach(function(r){t[r]=function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];return i.apply(void 0,[o+"."+r].concat(t))}}),t}h('Require unknown module "'+o+"\".It may not exist or haven't been registered.")}}var _="[[WorkerPageReady]]",b="[[RendererPageReady]]",w="[[SendInitialState]]",k="[[ReceivedInitialState]]",S="[[WorkerPageStateChange]]",O="[[RendererPageStateChange]]",C="__WINDMILL_MODULE_GETTER__",e=function(){};e.prototype.$on=function(e,t){return void 0===t&&(t=o),d('$on "'+e+'"'),!e&&m("invalid event name "+e+" for windmill.$on."),t===o&&m("bind event "+e+" with no callback through windmill.$on."),this.bridge.onReceiveMessage({data:{type:e},origin:this.label,type:"Event"},t)},e.prototype.$once=function(e,t){return void 0===t&&(t=o),d('$once "'+e+'"'),!e&&m("invalid event name "+e+" for windmill.$once."),t===o&&m("bind event "+e+" with no callback through windmill.$once."),this.bridge.onReceiveMessage({data:{type:e,once:!0},origin:this.label,type:"Event"},t)},e.prototype.$off=function(e,t){return d('$off "'+e+'"'),!e&&m("invalid event name "+e+" for windmill.$off."),this.bridge.unbindEventListener("Event."+e,t)},e.prototype.$cycle=function(e,t){return void 0===t&&(t=o),d('$cycle "'+e+'"'),e&&/^app:|^page(:|@)/.test(e)||m("invalid lifecycle name "+e+" for windmill.$cycle."),t===o&&m("hook lifecycle "+e+" with no callback function through windmill.$cycle."),"AppWorker"!==this.label&&/^app:/.test(e)&&m("Shouldn't bind lifecycle hook for app in a page client."),this.bridge.onReceiveMessage({type:"Lifecycle",origin:this.label,data:{type:e}},t)},e.prototype.$decycle=function(e,t){return d('$decycle "'+e+'"'),e&&/^app:|^page(:|@)/.test(e)||m("invalid lifecycle name "+e+" for windmill.$decycle."),this.bridge.unbindEventListener("Lifecycle."+e,t)},e.prototype.$emit=function(e,t,n){return void 0===t&&(t={}),d('$emit("'+e+'")'),!e&&m("invalid event name "+e+" for windmill.$emit."),n&&n!==this.label?this.bridge.postMessage({data:{type:e,data:t},origin:this.label,target:n,type:"Event"}):this.bridge.emitEvent(""+e,t)},e.prototype.$callAsync=function(n,r){var o=this;return void 0===r&&(r={}),d('$callAsync "'+n+'"'),n||m("invalid method name "+n+" for windmill.$callAsync."),new Promise(function(e,t){o.bridge.dispatchMessage({type:"ModuleCall",origin:o.label,target:"AppWorker",data:{method:n,params:r}},e,t,!1)})},e.prototype.$call=function(e,t,n,r){return void 0===t&&(t={}),void 0===n&&(n=o),void 0===r&&(r=o),d('$call "'+e+'", params: '+JSON.stringify(t)),e||m("invalid method name "+e+" for windmill.$call."),this.bridge.dispatchMessage({type:"ModuleCall",origin:this.label,target:"AppWorker",data:{method:e,params:t}},n,r,!0)},e.prototype.$registerModules=function(e){!function(r,o){if(void 0===o&&(o=!1),!l(r))return v("Invalid parameter type! The module definition is not a plain object.");var e=function(t){var e=r[t];y[t]?o||h('The "'+t+'" module has already been registered.It would be overridden.'):y[t]=[];var n=y[t];Array.isArray(e)?e.forEach(function(e){-1===n.indexOf(e)?n.push(e):o||h('The "'+e+'" of the "'+t+'" module has already been registered.')}):v('Invalid parameter type! The method list of the "'+t+'" module should be an Array.')};for(var t in r)e(t)}(e,!0)},e.prototype.$getAvailableModules=function(){return function(e){var t={};try{t=JSON.parse(JSON.stringify(e))}catch(e){}return t}(y)};var x="[[EVENT_MAP]]";function E(e,t){var n=e[x];return Array.isArray(n[t])||(n[t]=[]),n[t]}var $,A=function(){d("Create new EventEmitter."),Object.defineProperty(this,x,{configurable:!1,enumerable:!1,writable:!1,value:{}})};function I(t){var n;try{n=JSON.stringify(t)}catch(e){n=t}m("failed to postMessage: "+n)}function j(e,t,n,r,o,i){var a=t+"."+n;return e.WindVane?e.WindVane.call(t,n,r,o,i):m("should have WindVane in global context"+(a?" to call "+a:"")+".")}A.prototype.on=function(e,t){d('EventEmitter: on("'+e+'")');var n=E(this,e);return n.push({listener:t,once:!1,callCount:0}),this},A.prototype.once=function(e,t){d('EventEmitter: once("'+e+'")');var n=E(this,e);return n.push({listener:t,once:!0,callCount:0}),this},A.prototype.off=function(e,t){d('EventEmitter: off("'+e+'"'+(t?", listener":"")+")");var n=this[x];if(t){var r=n[e];if(Array.isArray(r)){var o=r.findIndex(function(e){return e.listener===t});-1!==o&&r.splice(o,1)}}else delete n[e];return this};var M=!(A.prototype.emit=function(t){for(var e=arguments,n=[],r=arguments.length-1;0<r--;)n[r]=e[r+1];d('EventEmitter: emit("'+t+'", '+JSON.stringify(n)+")");var o=this[x],i=o[t];return Array.isArray(i)&&(o[t]=i.filter(function(e){try{e.listener.apply(null,n),e.callCount+=1}catch(e){return v('Failed to emit "'+t+'" event.'),v(e.toString()),!0}return!e.once})),this}),T=function(){this._messages=[]};T.prototype.postMessage=function(e){d("cache message in lazyMsgModule. "+JSON.stringify(e)),this._messages.push(e)},T.prototype.replaceWith=function(e){P=!1,this._messageModule=e,this._flush()},T.prototype._flush=function(){var t=this;this._messages.forEach(function(e){return t._messageModule.postMessage(e)})};var P,F,N=new T;function R(e,t){var n,r=e?(n=e).requireModule("@weex/windmill")||n.requireModule("windmill"):function(){if(!$){var t="undefined"!=typeof window?window:global;$={postMessage:function(e){return j(t,"Windmill","postMessage",e,function(){},I)},onmessage:function(e){if(console.debug("Set onMessage for webview."),!M)return M=!0,j(t,"Windmill","onMessage",{},e,I)}}}return $}();if(!r)return m("can't find message module ("+(e?"windmill module":"message module in webview")+")."),P=!0,N;if("function"==typeof t){d('Set the "onmessage" method to the bridge through callback.');try{r.onmessage(t)}catch(e){v('Failed to set the "onmessage" method to the bridge through callback.'),v(e.toString())}}return P&&N.replaceWith(r),r}function D(e){var t=e.match(/([^@]+)(@\S+)/);return t&&t[1]||e}var V=function(e,t){var a=this;void 0===t&&(t={}),d("Create a new RendererBridge."),F=t.isWeex,this._emitter=new A,d("Register onmessage api for "+(F?"Weex windmill module":"webview")+"."),F&&(this._weex=e),this._onMessage=function(e){if(d("Receive message from the worker. (message: "+JSON.stringify(e)+")"),!l(e)&&(v("The parameter of onmessage should be a plain object! Not "+c(e)),"string"==typeof e))try{e=JSON.parse(e)}catch(e){return void v("Failed to parse the message string. "+e.toString())}var t=e.type,n=e.data;void 0===n&&(n={});var r=e.origin,o=e.callbackId;switch(t){case"Callback":a._emitter.emit("callback@AppWorker:"+o,n);break;case"Event":var i=D(n.type);a._emitter.emit(t+"."+i,Object.assign({origin:r},n,{type:i}));break;case"Lifecycle":a._emitter.emit(t+"."+n.lifecycle,n.options);break;case"SetData":a._emitter.emit("Event.setdata",n);break;default:m('Unknown message type received from worker: "'+t+'"')}},R(e,this._onMessage)};V.prototype.dispatchMessage=function(t,n,r,e){d("Dispatch message to worker. (message: "+JSON.stringify(t)+")"),t.callbackId=this._genCallbackId(function(e){return e.status&&"SUCCESS"===e.status?n(e):(e.status,v("call API "+t.data.method+" from renderer failed: "+e.status+", "+e.error),r(e))},{keepAlive:e});try{t.keepAlive=!0,this.postMessage(t)}catch(e){r(e)}},V.prototype.postMessage=function(e){try{d("Call postMessage to worker. (message: "+JSON.stringify(e)+")"),R(this._weex,this._onMessage).postMessage(e)}catch(e){m(e.message||e.toString()||"postMessage failed.")}},V.prototype._genCallbackId=function(e,t){var n=t.keepAlive,r=t.callbackId,o=r||i();return this._emitter[n?"on":"once"]("callback@AppWorker:"+o,e),o},V.prototype.onReceiveMessage=function(e,t){var n=e.type,r=e.data;void 0===r&&(r={});var o=r.type;"Event"===n&&(o=D(o),r.type=o);var i=r.once?"once":"on";this._emitter[i](n+"."+o,t)},V.prototype.unbindEventListener=function(e,t){this._emitter.off(D(e),t)},V.prototype.emitEvent=function(e,t){void 0===t&&(t={});var n=D(e);this._emitter.emit("Event."+n,{type:n,data:t})};var L=function(n){function e(e,t){n.call(this),e&&l(e.config)&&(this._name=e.config.pageName||"",this.label=e.config.clientId||"",e.config.availableModules?(this.$registerModules(e.config.availableModules),this._gotAvailableModulesFromWeex=!0):h("No available modules in weex options.")),d("Create a new RendererRuntime. ("+this.label+", "+this._name+")"),this.bridge=new V(e,t),this._init()}return n&&(e.__proto__=n),((e.prototype=Object.create(n&&n.prototype)).constructor=e).prototype._init=function(){var t=this;this.bridge.onReceiveMessage({origin:"AppWorker",target:this.label,type:"Event",data:{type:"registerModules"}},function(e){e&&"registerModules"===e.type&&(d("Register available modules in renderer. ("+Object.keys(e.data)+")"),t.$registerModules(e.data))})},e.prototype.ready=function(){this.bridge.dispatchMessage({origin:this.label,target:"AppWorker",type:"Event",data:{type:"[[RendererRuntimeReady]]",data:{label:this.label,handshake:!this._gotAvailableModulesFromWeex}}},o,o)},e}(e),J=["$on","$once","$off","$emit","$cycle","$decycle","$call","$callAsync","$navTo","$getAvailableModules"];function W(e,t){var n=!(!e||!e.requireModule);!function(e){if(!e||!e.platform)return console.error("set logger environment failed.");Object.assign(u,e)}({platform:n&&e.config.env.platform,debugMode:n&&e.config.env.debugMode,isWeex:n}),d("Setup Windmill renderer framework."),e&&!e.requireModule&&(t=e,e=void 0),t||(t={}),d("Instantiate renderer in "+(((t=Object.assign({},t)).isWeex=n)?"Weex container":"WindVane container")+".");var o,i,r=new L(e,t),a=(o=r,i={},J.forEach(function(r){"function"==typeof o[r]&&(i[r]=function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];return o[r].apply(o,t)})}),i);return d("Prepare runtime APIs: "+JSON.stringify(J)),t.exposeModuleGetter&&s(C,g(function(){return a})),r.ready(),a}var q=/^@(windmill|weex)\/([\w_-]+)/;function B(i,e,t){if(!i.config||"windmill"!==i.config.container)return i;if("function"!=typeof i.requireModule)return i;var a=i.requireModule,s=t||g(function(){return e});return i.requireModule=function(e){var t="weex",n=e,r=q.exec(e);switch(r?(t=r[1],n=r[2]):"string"==typeof i.config.container&&(t=i.config.container),t){case"weex":return a.call(i,n);case"windmill":var o=s(n);return!o&&i.isRegisteredModule(n)?(h('Trying to call weex module "'+n+'" in windmill context!This is NOT a good practice, please use windmill module instead!'),a.call(i,n)):o;default:v('Failed to require scoped module "'+n+'", the "'+t+'" scope is unknown.')}},i}function U(s,c,e){var l={},n=e&&e.normalizeEventName||function(e){return e},r=!(!e||!e.noTriggerWorker);function o(e,t,n,r){void 0===r&&(r=!1);var o=c.getId();l[o]||(l[o]={});var i=l[o];if(i[e]||(i[e]=[]),i[e].push({handler:t,wrap:n}),r)return s.$once(e,n);s.$on(e,n)}var i={on:function(e,t){o(n(e),t,function(e){t.call(c.getVm(),e.data)})},once:function(e,t){o(n(e),t,function(e){t.call(c.getVm(),e.data)},!0)},off:function(e,t){!function(e,n){var t=c.getId(),r=l[t];if(!r)return h("Unbind event from page "+t+" with no event handlers.");var o,i,a=r[e];a?n?(a.forEach(function(e,t){e.handler===n&&(o=e,i=t)}),o&&o.wrap&&(a.splice(i,1),s.$off(e,o.wrap))):((l[t]||(l[t]={}))[e]=[],s.$off(e)):h("Unbind event '"+e+"' which has no event handler.")}(n(e),t)},emit:function(e,t){s.$emit(n(e),t),r&&s.$emit(e+"@"+c.getId(),t,"AppWorker")},call:"default"},a=function(){};return["on","off","emit","once","call"].reduce(function(e,t){var o,n="$"+t,r=i[t];return e[n]="function"==typeof r?r:"default"===r?(o=n,function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];var r=s[o];return r.apply(void 0,t)}):a,e},{})}var z="AppWorker";function H(e){switch(c(e)){case"Object":for(var t in e)H(e[t]);break;case"Array":e.forEach(H)}}return function(e){var a=e.createInstanceContext,t=Object.assign({},e);return t.createInstanceContext=function(e,t,n){var r=t&&t.weex;if(!r||"windmill"!==r.config.container)return a(e,t,n);var l,u,o=Object.assign({},a(e,t,n)),i=W(r);return o.weex=B(r,i),o.requireModule=function(e){return r.requireModule(e)},o.__vue_page__=(l=o,u=i,function(){function e(e,t){var n=this,r=t||l,o=r.Vue,i=r.weex,a=i.config,s=a.clientId,c=a.pageName;if(p("Create Page with id "+s+", pageName "+c+"."),this._id=i.config.clientId||null,this._name=i.config.pageName||null,this._vm=null,this._instanceContext=t||l,this._Vue=o,this._weex=i,this._windmill=u,this._hold=!1,this._options=e,this._state="function"==typeof e.data?e.data():e.data,e.data=function(){return n._state},o.prototype.$page=U(this._windmill,this),d("bind with $page: "+Object.keys(o.prototype.$page)),e._noLazy){p("Init vm instantly in Page constructor with no lazy.");try{this._initVm()}catch(e){v("[windmill-vue-renderer] init vm instantly failed: "+(e&&e.message))}}this._shakeHandsBeforeInit(),this._windmill.$once(w,this._onStateInit.bind(this))}return e.prototype.getVm=function(){return this._vm},e.prototype.getId=function(){return this._id},e.prototype._initVm=function(){var n=this,e=this._vm=new this._Vue(this._options),t=e.$options.data,r=0;e.$watch(function(){for(var e in t)H(t[e]);return r=(r+1)%2},function(e,t){n._hold?n._hold=!1:n._debouncedWatcherCb(e,t)},{sync:!0})},e.prototype._shakeHandsBeforeInit=function(){d("start handshaking with worker."),this._sendPageReady(),this._windmill.$once(_,this._onWorkerReady.bind(this))},e.prototype._sendPageReady=function(){d("Send "+b+" to worker."),this._windmill.$emit(b+"@"+this._id,{},z)},e.prototype._onWorkerReady=function(t){var n;try{n=JSON.stringify(t)}catch(e){n=t+""}d(_+" event received: "+n+".");var e=t.data,r=e.clientId,o=e.pageName;r&&(this._id=r),o&&(this._name=o),this._sendPageReady()},e.prototype._onStateInit=function(t){var n,r=this;try{n=JSON.stringify(t)}catch(e){n=t+""}d(w+" event received: "+n),this._windmill.$off(_),this._windmill.$on(S,this._onDataSync.bind(this));var e=t.data,o=t.origin,i=e.clientId,a=e.pageName,s=i||o;s&&(this._id=s),a&&(this._name=a),this._state=Object.assign(this._state||{},e.initialState||{}),this._windmill.$emit(k+"@"+this._id,{},z);var c=this._vm;if(d("debounce watcher callback for page data watcher binding."),this._debouncedWatcherCb=f(function(e,t){d("emit "+O+" event."),r._windmill.$emit(O+"@"+r._id,r._vm&&r._vm.$options.data,z)},1e3/60),c)this._mergeData(e);else try{p("Init vm after "+w+"."),this._initVm()}catch(e){v("[windmill-vue-renderer] "+(e&&e.message))}},e.prototype._onDataSync=function(t){var n;try{n=JSON.stringify(t)}catch(e){n=t+""}d(S+" event received: "+n);var e=t.data;this._mergeData(e,!0)},e.prototype._mergeData=function(e,t){void 0===t&&(t=!1);var n=this._vm,r=n.$options.data;for(var o in e)t&&(this._hold=!0),n.$set(r,o,e[o])},e}()),Object.freeze(o),o},t}}()});pi.Vue=gi(pi.Vue),function(e){var t=cr.init,n=cr.config;n.frameworks=e;var r=un.native,o=un.transformer;for(var i in dr)cr.service.register(i,dr[i]);cr.freezePrototype(),global.frameworkVersion=r,global.transformerVersion=o;var a=t(n),s=function(r){global[r]=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];var n=a[r].apply(a,e);return n instanceof Error&&console.error(n.toString()),n}};for(var c in a)s(c)}(pi),Object.freeze(Object),Object.freeze(Array),ln(di=Object.prototype,"__defineGetter__",hi="Object.prototype"),ln(di,"__defineSetter__",hi),ln(di,"__lookupGetter__",hi),ln(di,"__lookupSetter__",hi),ln(di,"constructor",hi),ln(di,"hasOwnProperty",hi),ln(di,"isPrototypeOf",hi),ln(di,"propertyIsEnumerable",hi),ln(di,"toLocaleString",hi),ln(di,"toString",hi),ln(di,"valueOf",hi),Object.seal(di),Object.freeze(Array.prototype),Object.freeze(String.prototype),Object.freeze(Number.prototype),Object.freeze(Boolean.prototype),ln(vi=Error.prototype,"name",mi="Error.prototype"),ln(vi,"message",mi),ln(vi,"toString",mi),ln(vi,"constructor",mi),Object.seal(vi),Object.freeze(Date.prototype),Object.freeze(RegExp.prototype),global.registerMethods(yi)});
+(this.nativeLog||function(e){console.log(e)})("Start JS Framework 0.29.0, Build at 2018-10-02 14:30. (Vue: 2.5.16-weex.5, Rax: 0.4.20)");var global=this,process={env:{}},setTimeout=global.setTimeout;!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define(t):t()}(0,function(){"use strict";var t,c,r,l;function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function n(e,t){return e(t={exports:{}},t.exports),t.exports}Array.from||(Array.from=(t=Object.prototype.toString,c=function(e){return"function"==typeof e||"[object Function]"===t.call(e)},r=Math.pow(2,53)-1,l=function(e){var t,n=(t=Number(e),isNaN(t)?0:0!==t&&isFinite(t)?(0<t?1:-1)*Math.floor(Math.abs(t)):t);return Math.min(Math.max(n,0),r)},function(e){var t=Object(e);if(null==e)throw new TypeError("Array.from requires an array-like object - not null or undefined");var n,r=1<arguments.length?arguments[1]:void 0;if(void 0!==r){if(!c(r))throw new TypeError("Array.from: when provided, the second argument must be a function");2<arguments.length&&(n=arguments[2])}for(var o,i=l(t.length),a=c(this)?Object(new this(i)):new Array(i),s=0;s<i;)o=t[s],a[s]=r?void 0===n?r(o,s):r.call(n,o,s):o,s+=1;return a.length=i,a}));var v=n(function(e){var t=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)}),m=n(function(e){var t=e.exports={version:"2.5.7"};"number"==typeof __e&&(__e=t)}),o=(m.version,function(e){return"object"==typeof e?null!==e:"function"==typeof e}),y=function(e){if(!o(e))throw TypeError(e+" is not an object!");return e},i=function(e){try{return!!e()}catch(e){return!0}},a=!i(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}),s=v.document,u=o(s)&&o(s.createElement),f=function(e){return u?s.createElement(e):{}},p=!a&&!i(function(){return 7!=Object.defineProperty(f("div"),"a",{get:function(){return 7}}).a}),d=Object.defineProperty,h={f:a?Object.defineProperty:function(e,t,n){if(y(e),t=function(e,t){if(!o(e))return e;var n,r;if(t&&"function"==typeof(n=e.toString)&&!o(r=n.call(e)))return r;if("function"==typeof(n=e.valueOf)&&!o(r=n.call(e)))return r;if(!t&&"function"==typeof(n=e.toString)&&!o(r=n.call(e)))return r;throw TypeError("Can't convert object to primitive value")}(t,!0),y(n),p)try{return d(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(e[t]=n.value),e}},k=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}},S=a?function(e,t,n){return h.f(e,t,k(1,n))}:function(e,t,n){return e[t]=n,e},g={}.hasOwnProperty,_=function(e,t){return g.call(e,t)},b=0,w=Math.random(),O=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++b+w).toString(36))},C=n(function(e){var i=O("src"),t="toString",n=Function[t],a=(""+n).split(t);m.inspectSource=function(e){return n.call(e)},(e.exports=function(e,t,n,r){var o="function"==typeof n;o&&(_(n,"name")||S(n,"name",t)),e[t]!==n&&(o&&(_(n,i)||S(n,i,e[t]?""+e[t]:a.join(String(t)))),e===v?e[t]=n:r?e[t]?e[t]=n:S(e,t,n):(delete e[t],S(e,t,n)))})(Function.prototype,t,function(){return"function"==typeof this&&this[i]||n.call(this)})}),x=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e},E=function(r,o,e){if(x(r),void 0===o)return r;switch(e){case 1:return function(e){return r.call(o,e)};case 2:return function(e,t){return r.call(o,e,t)};case 3:return function(e,t,n){return r.call(o,e,t,n)}}return function(){return r.apply(o,arguments)}},$="prototype",A=function(e,t,n){var r,o,i,a,s=e&A.F,c=e&A.G,l=e&A.S,u=e&A.P,f=e&A.B,p=c?v:l?v[t]||(v[t]={}):(v[t]||{})[$],d=c?m:m[t]||(m[t]={}),h=d[$]||(d[$]={});for(r in c&&(n=t),n)i=((o=!s&&p&&void 0!==p[r])?p:n)[r],a=f&&o?E(i,v):u&&"function"==typeof i?E(Function.call,i):i,p&&C(p,r,i,e&A.U),d[r]!=i&&S(d,r,a),u&&h[r]!=i&&(h[r]=i)};v.core=m,A.F=1,A.G=2,A.S=4,A.P=8,A.B=16,A.W=32,A.U=64,A.R=128;var j,I=A,M={}.toString,T=function(e){return M.call(e).slice(8,-1)},F=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==T(e)?e.split(""):Object(e)},P=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e},N=function(e){return F(P(e))},R=Math.ceil,D=Math.floor,V=function(e){return isNaN(e=+e)?0:(0<e?D:R)(e)},L=Math.min,J=function(e){return 0<e?L(V(e),9007199254740991):0},W=Math.max,q=Math.min,B=n(function(e){var t="__core-js_shared__",n=v[t]||(v[t]={});(e.exports=function(e,t){return n[e]||(n[e]=void 0!==t?t:{})})("versions",[]).push({version:m.version,mode:"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})}),U=B("keys"),z=function(e){return U[e]||(U[e]=O(e))},H=(j=!1,function(e,t,n){var r,o,i,a=N(e),s=J(a.length),c=(o=s,(r=V(r=n))<0?W(r+o,0):q(r,o));if(j&&t!=t){for(;c<s;)if((i=a[c++])!=i)return!0}else for(;c<s;c++)if((j||c in a)&&a[c]===t)return j||c||0;return!j&&-1}),X=z("IE_PROTO"),G="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","),K=Object.keys||function(e){return function(e,t){var n,r=N(e),o=0,i=[];for(n in r)n!=X&&_(r,n)&&i.push(n);for(;t.length>o;)_(r,n=t[o++])&&(~H(i,n)||i.push(n));return i}(e,G)},Z={f:Object.getOwnPropertySymbols},Y={f:{}.propertyIsEnumerable},Q=function(e){return Object(P(e))},ee=Object.assign,te=!ee||i(function(){var e={},t={},n=Symbol(),r="abcdefghijklmnopqrst";return e[n]=7,r.split("").forEach(function(e){t[e]=e}),7!=ee({},e)[n]||Object.keys(ee({},t)).join("")!=r})?function(e,t){for(var n=arguments,r=Q(e),o=arguments.length,i=1,a=Z.f,s=Y.f;i<o;)for(var c,l=F(n[i++]),u=a?K(l).concat(a(l)):K(l),f=u.length,p=0;p<f;)s.call(l,c=u[p++])&&(r[c]=l[c]);return r}:ee;I(I.S+I.F,"Object",{assign:te});m.Object.assign;Object.setPrototypeOf||(Object.setPrototypeOf=function(t,n){var r;function o(e,t){return r.call(e,t),e}try{(r=t.getOwnPropertyDescriptor(t.prototype,n).set).call({},null)}catch(e){if(t.prototype!=={}[n])return;r=function(e){this[n]=e},o.polyfill=o(o({},null),t.prototype)instanceof t}return o}(Object,"__proto__"));var ne=global.WXEnvironment;void 0===ne||"iOS"!==ne.platform||ne.__enable_native_promise__||(global.Promise=void 0);var re=n(function(e){var t=B("wks"),n=v.Symbol,r="function"==typeof n;(e.exports=function(e){return t[e]||(t[e]=r&&n[e]||(r?n:O)("Symbol."+e))}).store=t}),oe=re("toStringTag"),ie="Arguments"==T(function(){return arguments}()),ae=function(e){var t,n,r;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(n=function(e,t){try{return e[t]}catch(e){}}(t=Object(e),oe))?n:ie?T(t):"Object"==(r=T(t))&&"function"==typeof t.callee?"Arguments":r},se={};se[re("toStringTag")]="z",se+""!="[object z]"&&C(Object.prototype,"toString",function(){return"[object "+ae(this)+"]"},!0);var ce={},le=a?Object.defineProperties:function(e,t){y(e);for(var n,r=K(t),o=r.length,i=0;i<o;)h.f(e,n=r[i++],t[n]);return e},ue=v.document,fe=ue&&ue.documentElement,pe=z("IE_PROTO"),de=function(){},he="prototype",ve=function(){var e,t=f("iframe"),n=G.length;for(t.style.display="none",fe.appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write("<script>document.F=Object<\/script>"),e.close(),ve=e.F;n--;)delete ve[he][G[n]];return ve()},me=Object.create||function(e,t){var n;return null!==e?(de[he]=y(e),n=new de,de[he]=null,n[pe]=e):n=ve(),void 0===t?n:le(n,t)},ye=h.f,ge=re("toStringTag"),_e=function(e,t,n){e&&!_(e=n?e:e.prototype,ge)&&ye(e,ge,{configurable:!0,value:t})},be={};S(be,re("iterator"),function(){return this});var we,ke=z("IE_PROTO"),Se=Object.prototype,Oe=Object.getPrototypeOf||function(e){return e=Q(e),_(e,ke)?e[ke]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?Se:null},Ce=re("iterator"),xe=!([].keys&&"next"in[].keys()),Ee="values",$e=function(){return this},Ae=function(e,t,n,r,o,i,a){var s,c,l;c=t,l=r,(s=n).prototype=me(be,{next:k(1,l)}),_e(s,c+" Iterator");var u,f,p,d=function(e){if(!xe&&e in y)return y[e];switch(e){case"keys":case Ee:return function(){return new n(this,e)}}return function(){return new n(this,e)}},h=t+" Iterator",v=o==Ee,m=!1,y=e.prototype,g=y[Ce]||y["@@iterator"]||o&&y[o],_=g||d(o),b=o?v?d("entries"):_:void 0,w="Array"==t&&y.entries||g;if(w&&(p=Oe(w.call(new e)))!==Object.prototype&&p.next&&(_e(p,h,!0),"function"!=typeof p[Ce]&&S(p,Ce,$e)),v&&g&&g.name!==Ee&&(m=!0,_=function(){return g.call(this)}),(xe||m||!y[Ce])&&S(y,Ce,_),ce[t]=_,ce[h]=$e,o)if(u={values:v?_:d(Ee),keys:i?_:d("keys"),entries:b},a)for(f in u)f in y||C(y,f,u[f]);else I(I.P+I.F*(xe||m),t,u);return u},je=(we=!0,function(e,t){var n,r,o=String(P(e)),i=V(t),a=o.length;return i<0||a<=i?we?"":void 0:(n=o.charCodeAt(i))<55296||56319<n||i+1===a||(r=o.charCodeAt(i+1))<56320||57343<r?we?o.charAt(i):n:we?o.slice(i,i+2):r-56320+(n-55296<<10)+65536});Ae(String,"String",function(e){this._t=String(e),this._i=0},function(){var e,t=this._t,n=this._i;return n>=t.length?{value:void 0,done:!0}:(e=je(t,n),this._i+=e.length,{value:e,done:!1})});var Ie=re("unscopables"),Me=Array.prototype;null==Me[Ie]&&S(Me,Ie,{});var Te=function(e){Me[Ie][e]=!0},Fe=function(e,t){return{value:t,done:!!e}},Pe=Ae(Array,"Array",function(e,t){this._t=N(e),this._i=0,this._k=t},function(){var e=this._t,t=this._k,n=this._i++;return!e||n>=e.length?(this._t=void 0,Fe(1)):Fe(0,"keys"==t?n:"values"==t?e[n]:[n,e[n]])},"values");ce.Arguments=ce.Array,Te("keys"),Te("values"),Te("entries");for(var Ne=re("iterator"),Re=re("toStringTag"),De=ce.Array,Ve={CSSRuleList:!0,CSSStyleDeclaration:!1,CSSValueList:!1,ClientRectList:!1,DOMRectList:!1,DOMStringList:!1,DOMTokenList:!0,DataTransferItemList:!1,FileList:!1,HTMLAllCollection:!1,HTMLCollection:!1,HTMLFormElement:!1,HTMLSelectElement:!1,MediaList:!0,MimeTypeArray:!1,NamedNodeMap:!1,NodeList:!0,PaintRequestList:!1,Plugin:!1,PluginArray:!1,SVGLengthList:!1,SVGNumberList:!1,SVGPathSegList:!1,SVGPointList:!1,SVGStringList:!1,SVGTransformList:!1,SourceBufferList:!1,StyleSheetList:!0,TextTrackCueList:!1,TextTrackList:!1,TouchList:!1},Le=K(Ve),Je=0;Je<Le.length;Je++){var We,qe=Le[Je],Be=Ve[qe],Ue=v[qe],ze=Ue&&Ue.prototype;if(ze&&(ze[Ne]||S(ze,Ne,De),ze[Re]||S(ze,Re,qe),ce[qe]=De,Be))for(We in Pe)ze[We]||C(ze,We,Pe[We],!0)}var He,Xe,Ge,Ke=function(t,e,n,r){try{return r?e(y(n)[0],n[1]):e(n)}catch(e){var o=t.return;throw void 0!==o&&y(o.call(t)),e}},Ze=re("iterator"),Ye=Array.prototype,Qe=re("iterator"),et=m.getIteratorMethod=function(e){if(null!=e)return e[Qe]||e["@@iterator"]||ce[ae(e)]},tt=n(function(e){var d={},h={},t=e.exports=function(e,t,n,r,o){var i,a,s,c,l,u=o?function(){return e}:et(e),f=E(n,r,t?2:1),p=0;if("function"!=typeof u)throw TypeError(e+" is not iterable!");if(void 0===(l=u)||ce.Array!==l&&Ye[Ze]!==l){for(s=u.call(e);!(a=s.next()).done;)if((c=Ke(s,f,a.value,t))===d||c===h)return c}else for(i=J(e.length);p<i;p++)if((c=t?f(y(a=e[p])[0],a[1]):f(e[p]))===d||c===h)return c};t.BREAK=d,t.RETURN=h}),nt=re("species"),rt=v.process,ot=v.setImmediate,it=v.clearImmediate,at=v.MessageChannel,st=v.Dispatch,ct=0,lt={},ut="onreadystatechange",ft=function(){var e=+this;if(lt.hasOwnProperty(e)){var t=lt[e];delete lt[e],t()}},pt=function(e){ft.call(e.data)};ot&&it||(ot=function(e){for(var t=arguments,n=[],r=1;arguments.length>r;)n.push(t[r++]);return lt[++ct]=function(){!function(e,t,n){var r=void 0===n;switch(t.length){case 0:return r?e():e.call(n);case 1:return r?e(t[0]):e.call(n,t[0]);case 2:return r?e(t[0],t[1]):e.call(n,t[0],t[1]);case 3:return r?e(t[0],t[1],t[2]):e.call(n,t[0],t[1],t[2]);case 4:return r?e(t[0],t[1],t[2],t[3]):e.call(n,t[0],t[1],t[2],t[3])}e.apply(n,t)}("function"==typeof e?e:Function(e),n)},He(ct),ct},it=function(e){delete lt[e]},"process"==T(rt)?He=function(e){rt.nextTick(E(ft,e,1))}:st&&st.now?He=function(e){st.now(E(ft,e,1))}:at?(Ge=(Xe=new at).port2,Xe.port1.onmessage=pt,He=E(Ge.postMessage,Ge,1)):v.addEventListener&&"function"==typeof postMessage&&!v.importScripts?(He=function(e){v.postMessage(e+"","*")},v.addEventListener("message",pt,!1)):He=ut in f("script")?function(e){fe.appendChild(f("script"))[ut]=function(){fe.removeChild(this),ft.call(e)}}:function(e){setTimeout(E(ft,e,1),0)});var dt={set:ot,clear:it},ht=dt.set,vt=v.MutationObserver||v.WebKitMutationObserver,mt=v.process,yt=v.Promise,gt="process"==T(mt);function _t(e){var n,r;this.promise=new e(function(e,t){if(void 0!==n||void 0!==r)throw TypeError("Bad Promise constructor");n=e,r=t}),this.resolve=x(n),this.reject=x(r)}var bt={f:function(e){return new _t(e)}},wt=function(e){try{return{e:!1,v:e()}}catch(e){return{e:!0,v:e}}},kt=v.navigator,St=kt&&kt.userAgent||"",Ot=re("species"),Ct=re("iterator"),xt=!1;try{[7][Ct]().return=function(){xt=!0}}catch(e){}var Et,$t,At,jt,It,Mt=dt.set,Tt=function(){var n,r,o,e=function(){var e,t;for(gt&&(e=mt.domain)&&e.exit();n;){t=n.fn,n=n.next;try{t()}catch(e){throw n?o():r=void 0,e}}r=void 0,e&&e.enter()};if(gt)o=function(){mt.nextTick(e)};else if(!vt||v.navigator&&v.navigator.standalone)if(yt&&yt.resolve){var t=yt.resolve(void 0);o=function(){t.then(e)}}else o=function(){ht.call(v,e)};else{var i=!0,a=document.createTextNode("");new vt(e).observe(a,{characterData:!0}),o=function(){a.data=i=!i}}return function(e){var t={fn:e,next:void 0};r&&(r.next=t),n||(n=t,o()),r=t}}(),Ft="Promise",Pt=v.TypeError,Nt=v.process,Rt=Nt&&Nt.versions,Dt=Rt&&Rt.v8||"",Vt=v[Ft],Lt="process"==ae(Nt),Jt=function(){},Wt=$t=bt.f,qt=!!function(){try{var e=Vt.resolve(1),t=(e.constructor={})[re("species")]=function(e){e(Jt,Jt)};return(Lt||"function"==typeof PromiseRejectionEvent)&&e.then(Jt)instanceof t&&0!==Dt.indexOf("6.6")&&-1===St.indexOf("Chrome/66")}catch(e){}}(),Bt=function(e){var t;return!(!o(e)||"function"!=typeof(t=e.then))&&t},Ut=function(u,n){if(!u._n){u._n=!0;var r=u._c;Tt(function(){for(var c=u._v,l=1==u._s,e=0,t=function(e){var t,n,r,o=l?e.ok:e.fail,i=e.resolve,a=e.reject,s=e.domain;try{o?(l||(2==u._h&&Xt(u),u._h=1),!0===o?t=c:(s&&s.enter(),t=o(c),s&&(s.exit(),r=!0)),t===e.promise?a(Pt("Promise-chain cycle")):(n=Bt(t))?n.call(t,i,a):i(t)):a(c)}catch(e){s&&!r&&s.exit(),a(e)}};r.length>e;)t(r[e++]);u._c=[],u._n=!1,n&&!u._h&&zt(u)})}},zt=function(i){Mt.call(v,function(){var e,t,n,r=i._v,o=Ht(i);if(o&&(e=wt(function(){Lt?Nt.emit("unhandledRejection",r,i):(t=v.onunhandledrejection)?t({promise:i,reason:r}):(n=v.console)&&n.error&&n.error("Unhandled promise rejection",r)}),i._h=Lt||Ht(i)?2:1),i._a=void 0,o&&e.e)throw e.v})},Ht=function(e){return 1!==e._h&&0===(e._a||e._c).length},Xt=function(t){Mt.call(v,function(){var e;Lt?Nt.emit("rejectionHandled",t):(e=v.onrejectionhandled)&&e({promise:t,reason:t._v})})},Gt=function(e){var t=this;t._d||(t._d=!0,(t=t._w||t)._v=e,t._s=2,t._a||(t._a=t._c.slice()),Ut(t,!0))},Kt=function(e){var n,r=this;if(!r._d){r._d=!0,r=r._w||r;try{if(r===e)throw Pt("Promise can't be resolved itself");(n=Bt(e))?Tt(function(){var t={_w:r,_d:!1};try{n.call(e,E(Kt,t,1),E(Gt,t,1))}catch(e){Gt.call(t,e)}}):(r._v=e,r._s=1,Ut(r,!1))}catch(e){Gt.call({_w:r,_d:!1},e)}}};qt||(Vt=function(e){!function(e,t,n,r){if(!(e instanceof t)||void 0!==r&&r in e)throw TypeError(n+": incorrect invocation!")}(this,Vt,Ft,"_h"),x(e),Et.call(this);try{e(E(Kt,this,1),E(Gt,this,1))}catch(e){Gt.call(this,e)}},(Et=function(e){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1}).prototype=function(e,t,n){for(var r in t)C(e,r,t[r],n);return e}(Vt.prototype,{then:function(e,t){var n,r,o,i=Wt((n=Vt,void 0===(o=y(this).constructor)||null==(r=y(o)[nt])?n:x(r)));return i.ok="function"!=typeof e||e,i.fail="function"==typeof t&&t,i.domain=Lt?Nt.domain:void 0,this._c.push(i),this._a&&this._a.push(i),this._s&&Ut(this,!1),i.promise},catch:function(e){return this.then(void 0,e)}}),At=function(){var e=new Et;this.promise=e,this.resolve=E(Kt,e,1),this.reject=E(Gt,e,1)},bt.f=Wt=function(e){return e===Vt||e===jt?new At(e):$t(e)}),I(I.G+I.W+I.F*!qt,{Promise:Vt}),_e(Vt,Ft),It=v[Ft],a&&It&&!It[Ot]&&h.f(It,Ot,{configurable:!0,get:function(){return this}}),jt=m[Ft],I(I.S+I.F*!qt,Ft,{reject:function(e){var t=Wt(this);return(0,t.reject)(e),t.promise}}),I(I.S+I.F*!qt,Ft,{resolve:function(e){return function(e,t){if(y(e),o(t)&&t.constructor===e)return t;var n=bt.f(e);return(0,n.resolve)(t),n.promise}(this,e)}}),I(I.S+I.F*!(qt&&function(e,t){if(!t&&!xt)return!1;var n=!1;try{var r=[7],o=r[Ct]();o.next=function(){return{done:n=!0}},r[Ct]=function(){return o},e(r)}catch(e){}return n}(function(e){Vt.all(e).catch(Jt)})),Ft,{all:function(e){var a=this,t=Wt(a),s=t.resolve,c=t.reject,n=wt(function(){var r=[],o=0,i=1;tt(e,!1,function(e){var t=o++,n=!1;r.push(void 0),i++,a.resolve(e).then(function(e){n||(n=!0,r[t]=e,--i||s(r))},c)}),--i||s(r)});return n.e&&c(n.v),t.promise},race:function(e){var t=this,n=Wt(t),r=n.reject,o=wt(function(){tt(e,!1,function(e){t.resolve(e).then(n.resolve,r)})});return o.e&&r(o.v),n.promise}});var Zt=["off","error","warn","info","log","debug"],Yt={};global.console;function Qt(e){var t=global.WXEnvironment&&global.WXEnvironment.logLevel||"log";return Yt[t]&&Yt[t][e]}function en(e){return e.map(function(e){return e="[object object]"===Object.prototype.toString.call(e).toLowerCase()?JSON.stringify(e):String(e)})}global.setTimeout;var tn=global.setTimeoutNative;function nn(t,n,r){if(t.hasOwnProperty(n)){var e=t[n];Object.defineProperty(t,n,{get:function(){return e},set:function(e){if(this===t)throw Error("Cannot assign to read only property "+n+" of "+r);return Object.defineProperty(this,n,{value:e,writable:!0}),e}})}}!function(){if(void 0===setTimeout&&"function"==typeof tn){var n={},r=0;global.setTimeout=function(e,t){n[++r]=e,tn(r.toString(),t)},global.setTimeoutCallback=function(e){"function"==typeof n[e]&&(n[e](),delete n[e])}}}(),"undefined"==typeof WXEnvironment||WXEnvironment.__enable_native_promise__,function(){if(Zt.forEach(function(n){var r=Zt.indexOf(n);Yt[n]={},Zt.forEach(function(e){var t=Zt.indexOf(e);t<=r&&(Yt[n][e]=!0)})}),global.WXEnvironment&&"Web"!==global.WXEnvironment.platform)global.console={debug:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];Qt("debug")&&global.nativeLog.apply(global,en(e).concat(["__DEBUG"]))},log:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];Qt("log")&&global.nativeLog.apply(global,en(e).concat(["__LOG"]))},info:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];Qt("info")&&global.nativeLog.apply(global,en(e).concat(["__INFO"]))},warn:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];Qt("warn")&&global.nativeLog.apply(global,en(e).concat(["__WARN"]))},error:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];Qt("error")&&global.nativeLog.apply(global,en(e).concat(["__ERROR"]))}};else{var e=console.debug,t=console.log,n=console.info,r=console.warn,o=console.error;console.__ori__={debug:e,log:t,info:n,warn:r,error:o},console.debug=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];Qt("debug")&&console.__ori__.debug.apply(console,e)},console.log=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];Qt("log")&&console.__ori__.log.apply(console,e)},console.info=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];Qt("info")&&console.__ori__.info.apply(console,e)},console.warn=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];Qt("warn")&&console.__ori__.warn.apply(console,e)},console.error=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];Qt("error")&&console.__ori__.error.apply(console,e)}}}();var rn={framework:"0.29.0",transformer:">=0.1.5 <0.5"};function on(e,t,n){return t+"@"+n+"#"+e}var an=function(e){this.instanceId=String(e),this.lastCallbackId=0,this.callbacks={},this.hooks={}};an.prototype.add=function(e){return this.lastCallbackId++,this.callbacks[this.lastCallbackId]=e,this.lastCallbackId},an.prototype.remove=function(e){var t=this.callbacks[e];return delete this.callbacks[e],t},an.prototype.registerHook=function(e,t,n,r){var o=on(e,t,n);this.hooks[o]&&console.warn('[JS Framework] Override an existing component hook "'+o+'".'),this.hooks[o]=r},an.prototype.triggerHook=function(e,t,n,r){var o=on(e,t,n),i=this.hooks[o];if("function"!=typeof i)return console.error("[JS Framework] Invalid hook function type ("+typeof i+') on "'+o+'".'),null;var a=null;try{a=i.apply(null,r||[])}catch(e){console.error('[JS Framework] Failed to execute the hook function on "'+o+'".')}return a},an.prototype.consume=function(e,t,n){var r=this.callbacks[e];if(void 0!==n&&!1!==n||delete this.callbacks[e],"function"==typeof r)try{return r.call(null,t)}catch(e){console.error("[JS Framework] Failed to execute the callback function:\n + "+e.toString())}return new Error('invalid callback id "'+e+'"')},an.prototype.close=function(){this.callbacks={},this.hooks={}};var sn=1;function cn(){return(sn++).toString()}function ln(e){var t=Object.prototype.toString.call(e);return t.substring(8,t.length-1)}function un(e){if("function"!=typeof btoa)return"";var t=Array.prototype.map.call(new Uint8Array(e),function(e){return String.fromCharCode(e)}).join("");return btoa(t)}function fn(e){if(!e||"object"!=typeof e)return!0;for(var t in e)if(Object.prototype.hasOwnProperty.call(e,t))return!1;return!0}var pn={};function dn(e){return pn[e]}function hn(e){var t=pn[e];return t&&t.taskCenter?t.taskCenter:null}function vn(e,t,n){var r=e.documentElement;if(!(0<r.pureChildren.length||t.parentNode)){var o,i,a=r.children,s=a.indexOf(n);s<0?a.push(t):a.splice(s,0,t),1===t.nodeType?("body"===t.role?(t.docId=e.id,t.ownerDocument=e,t.parentNode=r,yn(t,r)):(t.children.forEach(function(e){e.parentNode=t}),mn(e,t),t.docId=e.id,t.ownerDocument=e,yn(t,r),delete e.nodeMap[t.nodeId]),r.pureChildren.push(t),o=e,i=t.toJSON(),o&&o.taskCenter&&"function"==typeof o.taskCenter.send&&o.taskCenter.send("dom",{action:"createBody"},[i])):(t.parentNode=r,e.nodeMap[t.ref]=t)}}function mn(e,t){t.role="body",t.depth=1,delete e.nodeMap[t.nodeId],t.ref="_root",e.nodeMap._root=t,e.body=t}function yn(t,e){(t.parentNode=e).docId&&(t.docId=e.docId,t.ownerDocument=e.ownerDocument,(t.ownerDocument.nodeMap[t.nodeId]=t).depth=e.depth+1),t.children.forEach(function(e){yn(e,t)})}function gn(e){for(;e;){if(1===e.nodeType)return e;e=e.nextSibling}}function _n(e){for(;e;){if(1===e.nodeType)return e;e=e.previousSibling}}function bn(e,t,n,r){n<0&&(n=0);var o=t[n-1],i=t[n];return t.splice(n,0,e),r&&(o&&(o.nextSibling=e),e.previousSibling=o,(e.nextSibling=i)&&(i.previousSibling=e)),n}function wn(e,t,n,r){var o=t.indexOf(e);if(o<0)return-1;if(r){var i=t[o-1],a=t[o+1];i&&(i.nextSibling=a),a&&(a.previousSibling=i)}t.splice(o,1);var s=n;o<=n&&(s=n-1);var c=t[s-1],l=t[s];return t.splice(s,0,e),r&&(c&&(c.nextSibling=e),e.previousSibling=c,(e.nextSibling=l)&&(l.previousSibling=e)),o===s?-1:n}function kn(e,t,n){var r=t.indexOf(e);if(!(r<0)){if(n){var o=t[r-1],i=t[r+1];o&&(o.nextSibling=i),i&&(i.previousSibling=o)}t.splice(r,1)}}var Sn,On=function(){this.nodeId=cn(),this.ref=this.nodeId,this.children=[],this.pureChildren=[],this.parentNode=null,this.nextSibling=null,this.previousSibling=null};On.prototype.destroy=function(){var e=dn(this.docId);e&&(delete this.docId,delete e.nodeMap[this.nodeId]),this.children.forEach(function(e){e.destroy()})};var Cn={};var xn=["click","longpress","touchstart","touchmove","touchend","panstart","panmove","panend","horizontalpan","verticalpan","swipe"];function En(e,t){dn(e).nodeMap[t.nodeId]=t}var $n=function(o){function e(e,t,n){void 0===e&&(e="div"),o.call(this);var r=Cn[e];if(r&&!n)return new r(e,t,!0);t=t||{},this.nodeType=1,this.nodeId=cn(),this.ref=this.nodeId,this.type=e,this.attr=t.attr||{},this.style=t.style||{},this.classStyle=t.classStyle||{},this.event={},this.children=[],this.pureChildren=[]}return o&&(e.__proto__=o),((e.prototype=Object.create(o&&o.prototype)).constructor=e).prototype.appendChild=function(e){if(!e.parentNode||e.parentNode===this)if(e.parentNode){if(wn(e,this.children,this.children.length,!0),1===e.nodeType){var t=wn(e,this.pureChildren,this.pureChildren.length),n=hn(this.docId);if(n&&0<=t)return n.send("dom",{action:"moveElement"},[e.ref,this.ref,t])}}else if(yn(e,this),bn(e,this.children,this.children.length,!0),this.docId&&En(this.docId,e),1===e.nodeType){bn(e,this.pureChildren,this.pureChildren.length);var r=hn(this.docId);if(r)return r.send("dom",{action:"addElement"},[this.ref,e.toJSON(),-1])}},e.prototype.insertBefore=function(e,t){if(!(e.parentNode&&e.parentNode!==this||e===t||e.nextSibling&&e.nextSibling===t))if(e.parentNode){if(wn(e,this.children,this.children.indexOf(t),!0),1===e.nodeType){var n=gn(t),r=wn(e,this.pureChildren,n?this.pureChildren.indexOf(n):this.pureChildren.length),o=hn(this.docId);if(o&&0<=r)return o.send("dom",{action:"moveElement"},[e.ref,this.ref,r])}}else if(yn(e,this),bn(e,this.children,this.children.indexOf(t),!0),this.docId&&En(this.docId,e),1===e.nodeType){var i=gn(t),a=bn(e,this.pureChildren,i?this.pureChildren.indexOf(i):this.pureChildren.length),s=hn(this.docId);if(s)return s.send("dom",{action:"addElement"},[this.ref,e.toJSON(),a])}},e.prototype.insertAfter=function(e,t){if(!(e.parentNode&&e.parentNode!==this||e===t||e.previousSibling&&e.previousSibling===t))if(e.parentNode){if(wn(e,this.children,this.children.indexOf(t)+1,!0),1===e.nodeType){var n=wn(e,this.pureChildren,this.pureChildren.indexOf(_n(t))+1),r=hn(this.docId);if(r&&0<=n)return r.send("dom",{action:"moveElement"},[e.ref,this.ref,n])}}else if(yn(e,this),bn(e,this.children,this.children.indexOf(t)+1,!0),this.docId&&En(this.docId,e),1===e.nodeType){var o=bn(e,this.pureChildren,this.pureChildren.indexOf(_n(t))+1),i=hn(this.docId);if(i)return i.send("dom",{action:"addElement"},[this.ref,e.toJSON(),o])}},e.prototype.removeChild=function(e,t){if(e.parentNode&&(kn(e,this.children,!0),1===e.nodeType)){kn(e,this.pureChildren);var n=hn(this.docId);n&&n.send("dom",{action:"removeElement"},[e.ref])}t||e.destroy()},e.prototype.clear=function(){var t=hn(this.docId);t&&this.pureChildren.forEach(function(e){t.send("dom",{action:"removeElement"},[e.ref])}),this.children.forEach(function(e){e.destroy()}),this.children.length=0,this.pureChildren.length=0},e.prototype.setAttr=function(e,t,n){if(this.attr[e]!==t||!1===n){this.attr[e]=t;var r=hn(this.docId);if(!n&&r){var o={};o[e]=t,r.send("dom",{action:"updateAttrs"},[this.ref,o])}}},e.prototype.setAttrs=function(e,t){if(!fn(e)){var n={};for(var r in e)this.attr[r]!==e[r]&&(this.attr[r]=e[r],n[r]=e[r]);if(!fn(n)){var o=hn(this.docId);!t&&o&&o.send("dom",{action:"updateAttrs"},[this.ref,n])}}},e.prototype.setStyle=function(e,t,n){if(this.style[e]!==t||!1===n){this.style[e]=t;var r=hn(this.docId);if(!n&&r){var o={};o[e]=t,r.send("dom",{action:"updateStyle"},[this.ref,o])}}},e.prototype.setStyles=function(e,t){if(!fn(e)){var n={};for(var r in e)this.style[r]!==e[r]&&(this.style[r]=e[r],n[r]=e[r]);if(!fn(n)){var o=hn(this.docId);!t&&o&&o.send("dom",{action:"updateStyle"},[this.ref,n])}}},e.prototype.setClassStyle=function(e){for(var t in this.classStyle)this.classStyle[t]="";Object.assign(this.classStyle,e);var n=hn(this.docId);n&&n.send("dom",{action:"updateStyle"},[this.ref,this.toStyle()])},e.prototype.addEvent=function(e,t,n){if(this.event||(this.event={}),!this.event[e]){this.event[e]={handler:t,params:n};var r=hn(this.docId);r&&r.send("dom",{action:"addEvent"},[this.ref,e])}},e.prototype.removeEvent=function(e){if(this.event&&this.event[e]){delete this.event[e];var t=hn(this.docId);t&&t.send("dom",{action:"removeEvent"},[this.ref,e])}},e.prototype.fireEvent=function(t,e,n,r){var o=null,i=!1,a=this.event[t];if(a&&e){var s=a.handler;e.stopPropagation=function(){i=!0};try{o=r&&r.params?s.call.apply(s,[this].concat(r.params,[e])):s.call(this,e)}catch(e){console.error('[JS Framework] Failed to invoke the event handler of "'+t+'" on '+this.type+" ("+this.ref+"):\n "+e.toString())}}return!i&&n&&-1!==xn.indexOf(t)&&this.parentNode&&this.parentNode.fireEvent&&(e.currentTarget=this.parentNode,this.parentNode.fireEvent(t,e,n)),o},e.prototype.toStyle=function(){return Object.assign({},this.classStyle,this.style)},e.prototype.toJSON=function(){var e={ref:this.ref.toString(),type:this.type,attr:this.attr,style:this.toStyle()},t=[];for(var n in this.event){var r=this.event[n].params;r?t.push({type:n,params:r}):t.push(n)}return t.length&&(e.event=t),this.pureChildren.length&&(e.children=this.pureChildren.map(function(e){return e.toJSON()})),e},e.prototype.toString=function(){return"<"+this.type+" attr="+JSON.stringify(this.attr)+" style="+JSON.stringify(this.toStyle())+">"+this.pureChildren.map(function(e){return e.toString()}).join("")+"</"+this.type+">"},e}(On);Sn=$n;var An=function(){},jn=function(e,t){Object.defineProperty(this,"instanceId",{enumerable:!0,value:String(e)}),Object.defineProperty(this,"callbackManager",{enumerable:!0,value:new an(e)}),An=t||function(){}};function In(e,t){var n=dn(e);return n?Array.isArray(t)?t.map(function(e){switch(e.method){case"callback":return function(e,t,n,r){return e.taskCenter.callback(t,n,r)}.apply(void 0,[n].concat(e.args));case"fireEventSync":case"fireEvent":return function(e,t,n,r,o,i){var a=e.getRef(t);return a?e.fireEvent(a,n,r,o,i):new Error('invalid element reference "'+t+'"')}.apply(void 0,[n].concat(e.args));case"componentHook":return function(e,t,n,r,o){if(!e||!e.taskCenter)return console.error('[JS Framework] Can\'t find "document" or "taskCenter".'),null;var i=null;try{i=e.taskCenter.triggerHook(t,n,r,o)}catch(e){console.error('[JS Framework] Failed to trigger the "'+n+"@"+r+'" hook on '+t+".")}return i}.apply(void 0,[n].concat(e.args))}}):void 0:new Error("[JS Framework] Failed to receiveTasks, instance ("+e+") is not available.")}jn.prototype.callback=function(e,t,n){return this.callbackManager.consume(e,t,n)},jn.prototype.registerHook=function(){for(var e,t=[],n=arguments.length;n--;)t[n]=arguments[n];return(e=this.callbackManager).registerHook.apply(e,t)},jn.prototype.triggerHook=function(){for(var e,t=[],n=arguments.length;n--;)t[n]=arguments[n];return(e=this.callbackManager).triggerHook.apply(e,t)},jn.prototype.updateData=function(e,t,n){this.send("module",{module:"dom",method:"updateComponentData"},[e,t,n])},jn.prototype.destroyCallback=function(){return this.callbackManager.close()},jn.prototype.normalize=function(e,t){var n=this;void 0===t&&(t=!1);var r=ln(e);if(e&&e instanceof $n)return e.ref;if(e&&e._isVue&&e.$el instanceof $n)return e.$el.ref;if("Function"===r)return this.callbackManager.add(e).toString();if(t){if("Object"===r){var o={};for(var i in e)o[i]=n.normalize(e[i],!0);return o}if("Array"===r)return e.map(function(e){return n.normalize(e,!0)})}return e&&e.ref&&e["[[VirtualElement]]"]?e.ref:function(e){var t=ln(e);switch(t){case"Undefined":case"Null":return"";case"RegExp":return e.toString();case"Date":return e.toISOString();case"Number":case"String":case"Boolean":case"Array":case"Object":return e;case"ArrayBuffer":return{"@type":"binary",dataType:t,base64:un(e)};case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":return{"@type":"binary",dataType:t,base64:un(e.buffer)};default:return JSON.stringify(e)}}(e)},jn.prototype.send=function(e,t,n,r){var o=this,i=t.action,a=t.component,s=t.ref,c=t.module,l=t.method;switch(n=n.map(function(e){return o.normalize(e)}),"Object"===ln(r)&&(r=this.normalize(r,!0)),e){case"dom":return this[i](this.instanceId,n);case"component":return this.componentHandler(this.instanceId,s,l,n,Object.assign({component:a},r));default:return this.moduleHandler(this.instanceId,c,l,n,r)}},jn.prototype.callDOM=function(e,t){return this[e](this.instanceId,t)},jn.prototype.callComponent=function(e,t,n,r){return this.componentHandler(this.instanceId,e,t,n,r)},jn.prototype.callModule=function(e,t,n,r){return this.moduleHandler(this.instanceId,e,t,n,r)};var Mn={};function Tn(e){var t=function(t){Mn[t]||(Mn[t]={}),e[t].forEach(function(e){"string"==typeof e?Mn[t][e]=!0:Mn[t][e.name]=e.args})};for(var n in e)t(n)}function Fn(e,t){return"string"==typeof t?!(!Mn[e]||!Mn[e][t]):!!Mn[e]}var Pn={};function Nn(e){Array.isArray(e)&&e.forEach(function(e){e&&("string"==typeof e?Pn[e]=!0:"object"==typeof e&&"string"==typeof e.type&&function(o,e){if(e&&e.length){var t=function(e){function t(){e.apply(this,arguments)}return e&&(t.__proto__=e),(t.prototype=Object.create(e&&e.prototype)).constructor=t}(Sn);e.forEach(function(r){t.prototype[r]=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];var n=hn(this.docId);if(n)return n.send("component",{ref:this.ref,component:o,method:r},e)}}),Cn[o]=t}}((Pn[e.type]=e).type,e.methods))})}function Rn(e){return!!Pn[e]}var Dn=[];function Vn(e,t){Jn(e)?console.warn('Service "'+e+'" has been registered already!'):(t=Object.assign({},t),Dn.push({name:e,options:t}))}function Ln(n){Dn.some(function(e,t){if(e.name===n)return Dn.splice(t,1),!0})}function Jn(e){return t=e,0<=Dn.map(function(e){return e.name}).indexOf(t);var t}var Wn=function(t){function e(e){t.call(this),this.nodeType=8,this.nodeId=cn(),this.ref=this.nodeId,this.type="comment",this.value=e,this.children=[],this.pureChildren=[]}return t&&(e.__proto__=t),((e.prototype=Object.create(t&&t.prototype)).constructor=e).prototype.toString=function(){return"\x3c!-- "+this.value+" --\x3e"},e}(On);function qn(e,t){return void 0===t&&(t=[]),{module:"dom",method:e,args:t}}var Bn=function(e,t){this.id=e,this.batched=!1,this.updates=[],"function"==typeof t?Object.defineProperty(this,"handler",{configurable:!0,enumerable:!0,writable:!0,value:t}):console.error("[JS Runtime] invalid parameter, handler must be a function")};Bn.prototype.createFinish=function(e){return(0,this.handler)([qn("createFinish")],e)},Bn.prototype.updateFinish=function(e){return(0,this.handler)([qn("updateFinish")],e)},Bn.prototype.refreshFinish=function(e){return(0,this.handler)([qn("refreshFinish")],e)},Bn.prototype.createBody=function(e){var t=e.toJSON(),n=t.children;delete t.children;var r=[qn("createBody",[t])];return n&&r.push.apply(r,n.map(function(e){return qn("addElement",[t.ref,e,-1])})),this.addActions(r)},Bn.prototype.addElement=function(e,t,n){return 0<=n||(n=-1),this.addActions(qn("addElement",[t,e.toJSON(),n]))},Bn.prototype.removeElement=function(e){if(Array.isArray(e)){var t=e.map(function(e){return qn("removeElement",[e])});return this.addActions(t)}return this.addActions(qn("removeElement",[e]))},Bn.prototype.moveElement=function(e,t,n){return this.addActions(qn("moveElement",[e,t,n]))},Bn.prototype.setAttr=function(e,t,n){var r={};return r[t]=n,this.addActions(qn("updateAttrs",[e,r]))},Bn.prototype.setStyle=function(e,t,n){var r={};return r[t]=n,this.addActions(qn("updateStyle",[e,r]))},Bn.prototype.setStyles=function(e,t){return this.addActions(qn("updateStyle",[e,t]))},Bn.prototype.addEvent=function(e,t){return this.addActions(qn("addEvent",[e,t]))},Bn.prototype.removeEvent=function(e,t){return this.addActions(qn("removeEvent",[e,t]))},Bn.prototype.handler=function(e,t){return t&&t()},Bn.prototype.addActions=function(e){var t=this.updates,n=this.handler;if(Array.isArray(e)||(e=[e]),!this.batched)return n(e);t.push.apply(t,e)};var Un={createBody:"callCreateBody",addElement:"callAddElement",removeElement:"callRemoveElement",moveElement:"callMoveElement",updateAttrs:"callUpdateAttrs",updateStyle:"callUpdateStyle",addEvent:"callAddEvent",removeEvent:"callRemoveEvent"};function zn(e,t,n){var r,o=t.module,i=t.method,a=t.args;return r=i,"dom"===o&&Un[r]&&"function"==typeof global[Un[r]]?global[Un[i]].apply(global,[e].concat(a,["-1"])):n(e,[t],"-1")}var Hn=function e(t,n,r){var o,i;t=t?t.toString():"",this.id=t,this.URL=n,i=this,(o=t)&&(pn[o]=i),this.nodeMap={};var a,s,c=e.Listener||Bn;this.listener=new c(t,r||(a=t,"function"!=typeof(s=e.handler||global.callNative)&&console.error("[JS Runtime] no default handler"),function(e){Array.isArray(e)||(e=[e]);for(var t=0;t<e.length;t++){var n=zn(a,e[t],s);if(-1===n)return n}})),this.taskCenter=new jn(t,r?function(e){for(var t=[],n=arguments.length-1;0<n--;)t[n]=arguments[n+1];return r.apply(void 0,t)}:e.handler),this.createDocumentElement()};function Xn(e){return e["[[CurrentInstanceId]]"]}Hn.prototype.getRef=function(e){return this.nodeMap[e]},Hn.prototype.open=function(){this.listener.batched=!1},Hn.prototype.close=function(){this.listener.batched=!0},Hn.prototype.createDocumentElement=function(){var n=this;if(!this.documentElement){var e=new $n("document");e.docId=this.id,e.ownerDocument=this,e.role="documentElement",e.depth=0,e.ref="_documentElement",this.nodeMap._documentElement=e,this.documentElement=e,Object.defineProperty(e,"appendChild",{configurable:!0,enumerable:!0,writable:!0,value:function(e){vn(n,e)}}),Object.defineProperty(e,"insertBefore",{configurable:!0,enumerable:!0,writable:!0,value:function(e,t){vn(n,e,t)}})}return this.documentElement},Hn.prototype.createBody=function(e,t){this.body||mn(this,new $n(e,t));return this.body},Hn.prototype.createElement=function(e,t){return new $n(e,t)},Hn.prototype.createComment=function(e){return new Wn(e)},Hn.prototype.fireEvent=function(e,t,n,r,o){if(e){(n=n||{}).type=n.type||t,n.target=e,n.currentTarget=e,n.timestamp=Date.now(),r&&function(e,t){var n=t.attrs||{};for(var r in n)e.setAttr(r,n[r],!0);var o=t.style||{};for(var i in o)e.setStyle(i,o[i],!0)}(e,r);var i="true"===this.getRef("_root").attr.bubble;return e.fireEvent(t,n,i,o)}},Hn.prototype.destroy=function(){var e;this.taskCenter.destroyCallback(),delete this.listener,delete this.nodeMap,delete this.taskCenter,e=this.id,delete pn[e]},Hn.handler=null;var Gn,Kn,Zn=function(e,t){var n,r;n=this,r=String(e),Object.defineProperty(n,"[[CurrentInstanceId]]",{value:r}),this.config=t||{},this.document=new Hn(e,this.config.bundleUrl),this.requireModule=this.requireModule.bind(this),this.importScript=this.importScript.bind(this),this.isRegisteredModule=Fn,this.isRegisteredComponent=Rn};Zn.prototype.requireModule=function(s){var c=Xn(this);if(c&&this.document&&this.document.taskCenter){if(Fn(s)){var e={},t=Mn[s],n=function(a){Object.defineProperty(e,a,{enumerable:!0,configurable:!0,get:function(){return n=s,r=a,(o=hn(e=c))&&"function"==typeof o.send?function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return o.send("module",{module:n,method:r},e)}:(console.error("[JS Framework] Failed to find taskCenter ("+e+")."),null);var e,n,r,o},set:function(e){return n=s,r=a,o=e,(i=hn(t=c))&&"function"==typeof i.send?"function"!=typeof o?(console.error("[JS Framework] "+n+"."+r+" must be assigned as a function."),null):function(e){return i.send("module",{module:n,method:r},[e])}:(console.error("[JS Framework] Failed to find taskCenter ("+t+")."),null);var t,n,r,o,i}})};for(var r in t)n(r);return e}console.warn('[JS Framework] using unregistered weex module "'+s+'"')}else console.error('[JS Framework] Failed to requireModule("'+s+'"), instance ('+c+") doesn't exist anymore.")},Zn.prototype.supports=function(e){if("string"!=typeof e)return null;var t=e.match(/^@(\w+)\/([\w-]+)(\.(\w+))?$/i);if(t){var n=t[1],r=t[2],o=t[4];switch(n){case"module":return Fn(r,o);case"component":return Rn(r)}}return null},Zn.prototype.importScript=function(e,r){void 0===r&&(r={});var o=Xn(this),i=hn(o);return new Promise(function(t,n){i&&"function"==typeof i.send||n(new Error('[JS Framework] Failed to import script "'+e+'", no taskCenter ('+o+") matched."));try{i.send("module",{module:"script",method:"importScript"},[e,r],{callback:[function(e){return t(e)},function(e){return n(e)}]})}catch(e){n(e)}})};var Yn=/^\s*\/\/ *(\{[^}]*\}) *\r?\n/;function Qn(){return"0.29.0"}var er={};function tr(e){return er[e]}function nr(e,t,n){void 0===t&&(t={});var r=new Zn(e,t),o=t.bundleType||"Vue";er[e]=o;var i=Kn.frameworks[o];if(!i)return new Error('[JS Framework] Invalid bundle type "'+o+'".');var a,s,c,l,u=(a=e,s={weex:r,config:t,created:Date.now(),framework:o,bundleType:o},c=Kn,(l=Object.create(null)).service=Object.create(null),Dn.forEach(function(e){var t=e.name,n=e.options.create;if(n)try{var r=n(a,s,c);Object.assign(l.service,r),Object.assign(l,r.instance)}catch(e){console.error("[JS Runtime] Failed to create service "+t+".")}}),delete l.service.instance,Object.freeze(l.service),l);Object.freeze(u);var f=Object.create(null);Object.assign(f,u,{weex:r,getJSFMVersion:Qn,requireModule:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return r.requireModule.apply(r,e)},__WEEX_CALL_JAVASCRIPT__:In,services:u}),Object.freeze(f);var p=Object.assign({},f);return"function"==typeof i.createInstanceContext&&Object.assign(p,i.createInstanceContext(e,f,n)),Object.freeze(p),p}var rr={createInstance:function(e,t,n,r){if(er[e])return new Error('The instance id "'+e+'" has already been used!');var o=function(e){var t=Yn.exec(e);if(t)try{return JSON.parse(t[1]).framework}catch(e){}return"Weex"}(t);er[e]=o,(n=JSON.parse(JSON.stringify(n||{}))).env=JSON.parse(JSON.stringify(global.WXEnvironment||{})),n.bundleType=o;var i=Kn.frameworks[o];if(!i)return new Error('[JS Framework] Invalid bundle type "'+o+'".');"Weex"===o&&console.error('[JS Framework] COMPATIBILITY WARNING: Weex DSL 1.0 (.we) framework is no longer supported! It will be removed in the next version of WeexSDK, your page would be crash if you still using the ".we" framework. Please upgrade it to Vue.js or Rax.');var a=nr(e,n,r);if("function"==typeof i.createInstance){if("Rax"!==o&&"Weex"!==o)return i.createInstance(e,t,n,r,a);var s=Object.assign({config:n,created:Date.now(),framework:o},a);return i.createInstance(e,t,n,r,s)}!function(e,t){var n=[],r=[];for(var o in t)n.push(o),r.push(t[o]);var i="\n (function (global) {\n "+e+"\n })(Object.create(this))\n ";(new(Function.prototype.bind.apply(Function,[null].concat(n,[i])))).apply(void 0,r)}(t,a)},createInstanceContext:nr,getRoot:function(e){var t=dn(e);try{if(t&&t.body)return t.body.toJSON()}catch(e){return void console.error("[JS Framework] Failed to get the virtual dom tree.")}},getJSFMVersion:Qn,getDocument:dn,registerService:Vn,unregisterService:Ln,callJS:function(e,t){var n=Gn[tr(e)];return n&&"function"==typeof n.receiveTasks?n.receiveTasks(e,t):In(e,t)}};function or(s){rr[s]=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];var n,r=e[0],o=tr(r);if(o&&Gn[o]){var i=(n=Gn[o])[s].apply(n,e),a={framework:o};return"refreshInstance"===s?Dn.forEach(function(e){var t=e.options.refresh;t&&t(r,{info:a,runtime:Kn})}):"destroyInstance"===s&&(Dn.forEach(function(e){var t=e.options.destroy;t&&t(r,{info:a,runtime:Kn})}),delete er[r]),i}return new Error('[JS Framework] Using invalid instance id "'+r+'" when calling '+s+".")}}function ir(o,i){rr[o]=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];for(var n in"function"==typeof i&&i.apply(void 0,e),Kn.frameworks){var r=Kn.frameworks[n];r&&r[o]&&r[o].apply(r,e)}}}var ar={Document:Hn,Element:$n,Comment:Wn,Listener:Bn,TaskCenter:jn,sendTasks:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return"function"==typeof callNative?callNative.apply(void 0,e):(global.callNative||function(){}).apply(void 0,e)}};Hn.handler=ar.sendTasks;var sr={service:{register:Vn,unregister:Ln,has:Jn},freezePrototype:function(){Object.freeze(ar.Comment),Object.freeze(ar.Listener),Object.freeze(ar.Document.prototype),Object.freeze(ar.Comment.prototype),Object.freeze(ar.Listener.prototype)},init:function(e){for(var t in Gn=(Kn=e||{}).frameworks||{},function(){var e={createFinish:global.callCreateFinish,updateFinish:global.callUpdateFinish,refreshFinish:global.callRefreshFinish,createBody:global.callCreateBody,addElement:global.callAddElement,removeElement:global.callRemoveElement,moveElement:global.callMoveElement,updateAttrs:global.callUpdateAttrs,updateStyle:global.callUpdateStyle,addEvent:global.callAddEvent,removeEvent:global.callRemoveEvent},t=jn.prototype,n=function(n){var r=e[n];t[n]=r?function(e,t){return r.apply(void 0,[e].concat(t))}:function(e,t){return An(e,[{module:"dom",method:n,args:t}],"-1")}};for(var r in e)n(r);t.componentHandler=global.callNativeComponent||function(e,t,n,r,o){return An(e,[{component:o.component,ref:t,method:n,args:r}])},t.moduleHandler=global.callNativeModule||function(e,t,n,r){return An(e,[{module:t,method:n,args:r}])}}(),Gn){var n=Gn[t];if("function"==typeof n.init)try{n.init(e)}catch(e){}}return ir("registerComponents",Nn),ir("registerModules",Tn),ir("registerMethods"),["destroyInstance","refreshInstance"].forEach(or),rr},config:ar};function cr(e,t){void 0===t&&(t={}),this.type=e||"message",this.data=t.data||null,this.origin=t.origin||"",this.source=t.source||null,this.ports=t.ports||[],this.target=null,this.timeStamp=Date.now()}var lr={},ur={};function fr(){}fr.prototype.postMessage=function(e){if(this._closed)throw new Error('BroadcastChannel "'+this.name+'" is closed.');var t=lr[this.name];if(t&&t.length)for(var n=0;n<t.length;++n){var r=t[n];r._closed||r===this||"function"==typeof r.onmessage&&r.onmessage(new cr("message",{data:e}))}},fr.prototype.close=function(){var t=this;if(!this._closed&&(this._closed=!0,lr[this.name])){var e=lr[this.name].filter(function(e){return e!==t});e.length?lr[this.name]=e:delete lr[this.name]}};var pr={BroadcastChannel:{create:function(t,e,n){if(ur[t]=[],"function"==typeof global.BroadcastChannel)return{};var r={BroadcastChannel:function(e){Object.defineProperty(this,"name",{configurable:!1,enumerable:!0,writable:!1,value:String(e)}),this._closed=!1,this.onmessage=null,lr[this.name]||(lr[this.name]=[]),lr[this.name].push(this),ur[t].push(this)}};return r.BroadcastChannel.prototype=fr.prototype,{instance:r}},destroy:function(e,t){ur[e].forEach(function(e){return e.close()}),delete ur[e]}}};var dr={},hr={};var vr=Object.freeze({init:function(e){dr.Document=e.Document,dr.Element=e.Element,dr.Comment=e.Comment,dr.sendTasks=e.sendTasks},createInstance:function(t,e,n,r,o){void 0===n&&(n={}),void 0===r&&(r={}),void 0===o&&(o={});var i=new dr.Document(t,n.bundleUrl),a={},s={id:t,data:r,document:i,callbacks:a},c=0;i.addCallback=function(e){return a[++c]=e,c},i.handleCallback=function(e,t,n){var r=a[e];return n&&delete a[e],r(t)},hr[t]=s;var l=Object.assign({Document:dr.Document,Element:dr.Element,Comment:dr.Comment,sendTasks:function(e){return dr.sendTasks(t,e,-1)},options:n,document:i},o),u=[],f=[];for(var p in l)u.push(p),f.push(l[p]);return u.push(e),(new(Function.prototype.bind.apply(Function,[null].concat(u)))).apply(void 0,f),dr.sendTasks(t,[{module:"dom",method:"createFinish",args:[]}],-1),s},destroyInstance:function(e){delete hr[e]},getRoot:function(e){return hr[e].document.body.toJSON()},receiveTasks:function(r,e){var o={fireEvent:function(e,t,n,r,o){var i=hr[e].document,a=i.getRef(t);return i.fireEvent(a,n,r,o)},callback:function(e,t,n,r){return hr[e].document.handleCallback(t,n,r)}};if((hr[r]||{}).document&&Array.isArray(e)){var i=[];return e.forEach(function(e){var t=o[e.method],n=[].concat(e.args);"function"==typeof t&&(n.unshift(r),i.push(t.apply(void 0,n)))}),i}}}),mr=n(function(e){e.exports=function(e,o){var _=Object.freeze({});function $(e){return null==e}function A(e){return null!=e}function j(e){return!0===e}function I(e){return"string"==typeof e||"number"==typeof e||"symbol"==typeof e||"boolean"==typeof e}function b(e){return null!==e&&"object"==typeof e}var r=Object.prototype.toString;function u(e){return"[object Object]"===r.call(e)}function i(e){var t=parseFloat(String(e));return 0<=t&&Math.floor(t)===t&&isFinite(e)}function t(e){return null==e?"":"object"==typeof e?JSON.stringify(e,null,2):String(e)}function n(e){var t=parseFloat(e);return isNaN(t)?e:t}function s(e,t){for(var n=Object.create(null),r=e.split(","),o=0;o<r.length;o++)n[r[o]]=!0;return t?function(e){return n[e.toLowerCase()]}:function(e){return n[e]}}s("slot,component",!0);var c=s("key,ref,slot,slot-scope,is");function l(e,t){if(e.length){var n=e.indexOf(t);if(-1<n)return e.splice(n,1)}}var a=Object.prototype.hasOwnProperty;function f(e,t){return a.call(e,t)}function p(t){var n=Object.create(null);return function(e){return n[e]||(n[e]=t(e))}}var d=/-(\w)/g,h=p(function(e){return e.replace(d,function(e,t){return t?t.toUpperCase():""})}),v=p(function(e){return e.charAt(0).toUpperCase()+e.slice(1)}),m=/\B([A-Z])/g,w=p(function(e){return e.replace(m,"-$1").toLowerCase()});var y=Function.prototype.bind?function(e,t){return e.bind(t)}:function(n,r){function e(e){var t=arguments.length;return t?1<t?n.apply(r,arguments):n.call(r,e):n.call(r)}return e._length=n.length,e};function g(e,t){t=t||0;for(var n=e.length-t,r=new Array(n);n--;)r[n]=e[n+t];return r}function N(e,t){for(var n in t)e[n]=t[n];return e}function R(e,t,n){}var k=function(e,t,n){return!1},S=function(e){return e};function O(t,n){if(t===n)return!0;var e=b(t),r=b(n);if(!e||!r)return!e&&!r&&String(t)===String(n);try{var o=Array.isArray(t),i=Array.isArray(n);if(o&&i)return t.length===n.length&&t.every(function(e,t){return O(e,n[t])});if(o||i)return!1;var a=Object.keys(t),s=Object.keys(n);return a.length===s.length&&a.every(function(e){return O(t[e],n[e])})}catch(e){return!1}}function C(e,t){for(var n=0;n<e.length;n++)if(O(e[n],t))return n;return-1}function D(e){var t=!1;return function(){t||(t=!0,e.apply(this,arguments))}}var M="data-server-rendered",x=["component","directive","filter"],E=["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed","activated","deactivated","errorCaptured"],T={optionMergeStrategies:Object.create(null),silent:!1,productionTip:!1,devtools:!1,performance:!1,errorHandler:null,warnHandler:null,ignoredElements:[],keyCodes:Object.create(null),isReservedTag:k,isReservedAttr:k,isUnknownElement:k,getTagNamespace:R,parsePlatformTagName:S,mustUseProp:k,_lifecycleHooks:E};function F(e,t,n,r){Object.defineProperty(e,t,{value:n,enumerable:!!r,writable:!0,configurable:!0})}var P=/[^\w.$]/;var V,L="__proto__"in{},J="undefined"!=typeof window,W="undefined"!=typeof WXEnvironment&&!!WXEnvironment.platform,q=W&&WXEnvironment.platform.toLowerCase(),B=J&&window.navigator.userAgent.toLowerCase(),U=(B&&/msie|trident/.test(B),B&&0<B.indexOf("msie 9.0")),z=B&&0<B.indexOf("edge/"),H=(B&&B.indexOf("android"),B&&/iphone|ipad|ipod|ios/.test(B)||"ios"===q),X=(B&&/chrome\/\d+/.test(B),{}.watch);if(J)try{var G={};Object.defineProperty(G,"passive",{get:function(){}}),window.addEventListener("test-passive",null,G)}catch(e){}var K=function(){return void 0===V&&(V=!J&&!W&&void 0!==global&&"server"===global.process.env.VUE_ENV),V},Z=J&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function Y(e){return"function"==typeof e&&/native code/.test(e.toString())}var Q,ee="undefined"!=typeof Symbol&&Y(Symbol)&&"undefined"!=typeof Reflect&&Y(Reflect.ownKeys);Q="undefined"!=typeof Set&&Y(Set)?Set:function(){function e(){this.set=Object.create(null)}return e.prototype.has=function(e){return!0===this.set[e]},e.prototype.add=function(e){this.set[e]=!0},e.prototype.clear=function(){this.set=Object.create(null)},e}();var te=R,ne=0,re=function(){this.id=ne++,this.subs=[]};re.prototype.addSub=function(e){this.subs.push(e)},re.prototype.removeSub=function(e){l(this.subs,e)},re.prototype.depend=function(){re.target&&re.target.addDep(this)},re.prototype.notify=function(){for(var e=this.subs.slice(),t=0,n=e.length;t<n;t++)e[t].update()},re.target=null;var oe=[];function ie(e){re.target&&oe.push(re.target),re.target=e}function ae(){re.target=oe.pop()}var se=function(e,t,n,r,o,i,a,s){this.tag=e,this.data=t,this.children=n,this.text=r,this.elm=o,this.ns=void 0,this.context=i,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=t&&t.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=s,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1},ce={child:{configurable:!0}};ce.child.get=function(){return this.componentInstance},Object.defineProperties(se.prototype,ce);var le=function(e){void 0===e&&(e="");var t=new se;return t.text=e,t.isComment=!0,t};function ue(e){return new se(void 0,void 0,void 0,String(e))}function fe(e){var t=new se(e.tag,e.data,e.children,e.text,e.elm,e.context,e.componentOptions,e.asyncFactory);return t.ns=e.ns,t.isStatic=e.isStatic,t.key=e.key,t.isComment=e.isComment,t.fnContext=e.fnContext,t.fnOptions=e.fnOptions,t.fnScopeId=e.fnScopeId,t.isCloned=!0,t}var pe=Array.prototype,de=Object.create(pe);["push","pop","shift","unshift","splice","sort","reverse"].forEach(function(a){var s=pe[a];F(de,a,function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];var r,o=s.apply(this,t),i=this.__ob__;switch(a){case"push":case"unshift":r=t;break;case"splice":r=t.slice(2)}return r&&i.observeArray(r),i.dep.notify(),o})});var he=Object.getOwnPropertyNames(de),ve=!0;function me(e){ve=e}var ye=function(e){(this.value=e,this.dep=new re,this.vmCount=0,F(e,"__ob__",this),Array.isArray(e))?((L?ge:_e)(e,de,he),this.observeArray(e)):this.walk(e)};function ge(e,t,n){e.__proto__=t}function _e(e,t,n){for(var r=0,o=n.length;r<o;r++){var i=n[r];F(e,i,t[i])}}function be(e,t){var n;if(b(e)&&!(e instanceof se))return f(e,"__ob__")&&e.__ob__ instanceof ye?n=e.__ob__:ve&&!K()&&(Array.isArray(e)||u(e))&&Object.isExtensible(e)&&!e._isVue&&(n=new ye(e)),t&&n&&n.vmCount++,n}function we(n,e,r,t,o){var i=new re,a=Object.getOwnPropertyDescriptor(n,e);if(!a||!1!==a.configurable){var s=a&&a.get;s||2!==arguments.length||(r=n[e]);var c=a&&a.set,l=!o&&be(r);Object.defineProperty(n,e,{enumerable:!0,configurable:!0,get:function(){var e=s?s.call(n):r;return re.target&&(i.depend(),l&&(l.dep.depend(),Array.isArray(e)&&function e(t){for(var n=void 0,r=0,o=t.length;r<o;r++)(n=t[r])&&n.__ob__&&n.__ob__.dep.depend(),Array.isArray(n)&&e(n)}(e))),e},set:function(e){var t=s?s.call(n):r;e===t||e!=e&&t!=t||(c?c.call(n,e):r=e,l=!o&&be(e),i.notify())}})}}function ke(e,t,n){if(Array.isArray(e)&&i(t))return e.length=Math.max(e.length,t),e.splice(t,1,n),n;if(t in e&&!(t in Object.prototype))return e[t]=n;var r=e.__ob__;return e._isVue||r&&r.vmCount?n:r?(we(r.value,t,n),r.dep.notify(),n):e[t]=n}function Se(e,t){if(Array.isArray(e)&&i(t))e.splice(t,1);else{var n=e.__ob__;e._isVue||n&&n.vmCount||f(e,t)&&(delete e[t],n&&n.dep.notify())}}ye.prototype.walk=function(e){for(var t=Object.keys(e),n=0;n<t.length;n++)we(e,t[n])},ye.prototype.observeArray=function(e){for(var t=0,n=e.length;t<n;t++)be(e[t])};var Oe=T.optionMergeStrategies;function Ce(e,t){if(!t)return e;for(var n,r,o,i=Object.keys(t),a=0;a<i.length;a++)r=e[n=i[a]],o=t[n],f(e,n)?u(r)&&u(o)&&Ce(r,o):ke(e,n,o);return e}function xe(n,r,o){return o?function(){var e="function"==typeof r?r.call(o,o):r,t="function"==typeof n?n.call(o,o):n;return e?Ce(e,t):t}:r?n?function(){return Ce("function"==typeof r?r.call(this,this):r,"function"==typeof n?n.call(this,this):n)}:r:n}function Ee(e,t){return t?e?e.concat(t):Array.isArray(t)?t:[t]:e}function $e(e,t,n,r){var o=Object.create(e||null);return t?N(o,t):o}Oe.data=function(e,t,n){return n?xe(e,t,n):t&&"function"!=typeof t?e:xe(e,t)},E.forEach(function(e){Oe[e]=Ee}),x.forEach(function(e){Oe[e+"s"]=$e}),Oe.watch=function(e,t,n,r){if(e===X&&(e=void 0),t===X&&(t=void 0),!t)return Object.create(e||null);if(!e)return t;var o={};for(var i in N(o,e),t){var a=o[i],s=t[i];a&&!Array.isArray(a)&&(a=[a]),o[i]=a?a.concat(s):Array.isArray(s)?s:[s]}return o},Oe.props=Oe.methods=Oe.inject=Oe.computed=function(e,t,n,r){if(!e)return t;var o=Object.create(null);return N(o,e),t&&N(o,t),o},Oe.provide=xe;var Ae=function(e,t){return void 0===t?e:t};function je(n,r,o){"function"==typeof r&&(r=r.options),function(e,t){var n=e.props;if(n){var r,o,i={};if(Array.isArray(n))for(r=n.length;r--;)"string"==typeof(o=n[r])&&(i[h(o)]={type:null});else if(u(n))for(var a in n)o=n[a],i[h(a)]=u(o)?o:{type:o};e.props=i}}(r),function(e,t){var n=e.inject;if(n){var r=e.inject={};if(Array.isArray(n))for(var o=0;o<n.length;o++)r[n[o]]={from:n[o]};else if(u(n))for(var i in n){var a=n[i];r[i]=u(a)?N({from:i},a):{from:a}}}}(r),function(e){var t=e.directives;if(t)for(var n in t){var r=t[n];"function"==typeof r&&(t[n]={bind:r,update:r})}}(r);var e=r.extends;if(e&&(n=je(n,e,o)),r.mixins)for(var t=0,i=r.mixins.length;t<i;t++)n=je(n,r.mixins[t],o);var a,s={};for(a in n)c(a);for(a in r)f(n,a)||c(a);function c(e){var t=Oe[e]||Ae;s[e]=t(n[e],r[e],o,e)}return s}function Ie(e,t,n,r){if("string"==typeof n){var o=e[t];if(f(o,n))return o[n];var i=h(n);if(f(o,i))return o[i];var a=v(i);return f(o,a)?o[a]:o[n]||o[i]||o[a]}}function Me(e,t,n,r){var o=t[e],i=!f(n,e),a=n[e],s=Pe(Boolean,o.type);if(-1<s)if(i&&!f(o,"default"))a=!1;else if(""===a||a===w(e)){var c=Pe(String,o.type);(c<0||s<c)&&(a=!0)}if(void 0===a){a=function(e,t,n){if(!f(t,"default"))return;var r=t.default;if(e&&e.$options.propsData&&void 0===e.$options.propsData[n]&&void 0!==e._props[n])return e._props[n];return"function"==typeof r&&"Function"!==Te(t.type)?r.call(e):r}(r,o,e);var l=ve;me(!0),be(a),me(l)}return a}function Te(e){var t=e&&e.toString().match(/^\s*function (\w+)/);return t?t[1]:""}function Fe(e,t){return Te(e)===Te(t)}function Pe(e,t){if(!Array.isArray(t))return Fe(t,e)?0:-1;for(var n=0,r=t.length;n<r;n++)if(Fe(t[n],e))return n;return-1}function Ne(e,t,n){if(t)for(var r=t;r=r.$parent;){var o=r.$options.errorCaptured;if(o)for(var i=0;i<o.length;i++)try{if(!1===o[i].call(r,e,t,n))return}catch(e){Re(e,r,"errorCaptured hook")}}Re(e,t,n)}function Re(e,t,n){if(T.errorHandler)try{return T.errorHandler.call(null,e,t,n)}catch(e){De(e,null,"config.errorHandler")}De(e,t,n)}function De(e,t,n){if(!J&&!W||"undefined"==typeof console)throw e;console.error(e)}var Ve,Le,Je=[],We=!1;function qe(){We=!1;for(var e=Je.slice(0),t=Je.length=0;t<e.length;t++)e[t]()}var Be=!1;function Ue(){if("undefined"!=typeof setImmediate&&Y(setImmediate))Le=function(){setImmediate(qe)};else if("undefined"==typeof MessageChannel||!Y(MessageChannel)&&"[object MessageChannelConstructor]"!==MessageChannel.toString())Le=function(){setTimeout(qe,0)};else{var e=new MessageChannel,t=e.port2;e.port1.onmessage=qe,Le=function(){t.postMessage(1)}}if("undefined"!=typeof Promise&&Y(Promise)){var n=Promise.resolve();Ve=function(){n.then(qe),!W&&H&&setTimeout(R)}}else Ve=Le}function ze(e,t){var n;if(Je.push(function(){if(e)try{e.call(t)}catch(e){Ne(e,t,"nextTick")}else n&&n(t)}),We||(We=!0,Be&&"function"==typeof Le?Le():"function"==typeof Ve?Ve():setTimeout(qe,0)),!e&&"undefined"!=typeof Promise)return new Promise(function(e){n=e})}Ue();var He=new Q;function Xe(e){!function e(t,n){var r,o;var i=Array.isArray(t);if(!i&&!b(t)||Object.isFrozen(t)||t instanceof se)return;if(t.__ob__){var a=t.__ob__.dep.id;if(n.has(a))return;n.add(a)}if(i)for(r=t.length;r--;)e(t[r],n);else for(o=Object.keys(t),r=o.length;r--;)e(t[o[r]],n)}(e,He),He.clear()}var Ge,Ke=p(function(e){var t="&"===e.charAt(0),n="~"===(e=t?e.slice(1):e).charAt(0),r="!"===(e=n?e.slice(1):e).charAt(0);return{name:e=r?e.slice(1):e,once:n,capture:r,passive:t}});function Ze(e){function o(){var e=arguments,t=o.fns;if(!Array.isArray(t))return t.apply(null,arguments);for(var n=t.slice(),r=0;r<n.length;r++)n[r].apply(null,e)}return o.fns=e,o}function Ye(e,t,n,r,o){var i,a,s,c,l;for(i in e)a=s=e[i],c=t[i],l=Ke(i),u(a)&&(s=a.handler,l.params=a.params),$(s)||($(c)?($(s.fns)&&(s=e[i]=Ze(s)),n(l.name,s,l.once,l.capture,l.passive,l.params)):s!==c&&(c.fns=s,e[i]=c));for(i in t)$(e[i])&&r((l=Ke(i)).name,t[i],l.capture)}function Qe(e,t,n){var r;e instanceof se&&(e=e.data.hook||(e.data.hook={}));var o=e[t];function i(){n.apply(this,arguments),l(r.fns,i)}$(o)?r=Ze([i]):A(o.fns)&&j(o.merged)?(r=o).fns.push(i):r=Ze([o,i]),r.merged=!0,e[t]=r}function et(e,t,n,r,o){if(A(t)){if(f(t,n))return e[n]=t[n],o||delete t[n],!0;if(f(t,r))return e[n]=t[r],o||delete t[r],!0}return!1}function tt(e){return I(e)?[ue(e)]:Array.isArray(e)?function e(t,n){var r=[];var o,i,a,s;for(o=0;o<t.length;o++)$(i=t[o])||"boolean"==typeof i||(a=r.length-1,s=r[a],Array.isArray(i)?0<i.length&&(nt((i=e(i,(n||"")+"_"+o))[0])&&nt(s)&&(r[a]=ue(s.text+i[0].text),i.shift()),r.push.apply(r,i)):I(i)?nt(s)?r[a]=ue(s.text+i):""!==i&&r.push(ue(i)):nt(i)&&nt(s)?r[a]=ue(s.text+i.text):(j(t._isVList)&&A(i.tag)&&$(i.key)&&A(n)&&(i.key="__vlist"+n+"_"+o+"__"),r.push(i)));return r}(e):void 0}function nt(e){return A(e)&&A(e.text)&&!1===e.isComment}function rt(e,t){return(e.__esModule||ee&&"Module"===e[Symbol.toStringTag])&&(e=e.default),b(e)?t.extend(e):e}function ot(e){return e.isComment&&e.asyncFactory}function it(e){if(Array.isArray(e))for(var t=0;t<e.length;t++){var n=e[t];if(A(n)&&(A(n.componentOptions)||ot(n)))return n}}function at(e){e._events=Object.create(null),e._hasHookEvent=!1;var t=e.$options._parentListeners;t&<(e,t)}function st(e,t,n){n?Ge.$once(e,t):Ge.$on(e,t)}function ct(e,t){Ge.$off(e,t)}function lt(e,t,n){Ge=e,Ye(t,n||{},st,ct),Ge=void 0}function ut(e,t){var n={};if(!e)return n;for(var r=0,o=e.length;r<o;r++){var i=e[r],a=i.data;if(a&&a.attrs&&a.attrs.slot&&delete a.attrs.slot,i.context!==t&&i.fnContext!==t||!a||null==a.slot)(n.default||(n.default=[])).push(i);else{var s=a.slot,c=n[s]||(n[s]=[]);"template"===i.tag?c.push.apply(c,i.children||[]):c.push(i)}}for(var l in n)n[l].every(ft)&&delete n[l];return n}function ft(e){return e.isComment&&!e.asyncFactory||" "===e.text}function pt(e,t){t=t||{};for(var n=0;n<e.length;n++)Array.isArray(e[n])?pt(e[n],t):t[e[n].key]=e[n].fn;return t}var dt=null;function ht(e){var t=e.$options,n=t.parent;if(n&&!t.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(e)}e.$parent=n,e.$root=n?n.$root:e,e.$children=[],e.$refs={},e._watcher=null,e._inactive=null,e._directInactive=!1,e._isMounted=!1,e._isDestroyed=!1,e._isBeingDestroyed=!1}function vt(e){for(;e&&(e=e.$parent);)if(e._inactive)return!0;return!1}function mt(e,t){if(t){if(e._directInactive=!1,vt(e))return}else if(e._directInactive)return;if(e._inactive||null===e._inactive){e._inactive=!1;for(var n=0;n<e.$children.length;n++)mt(e.$children[n]);yt(e,"activated")}}function yt(t,n){ie();var e=t.$options[n];if(e)for(var r=0,o=e.length;r<o;r++)try{e[r].call(t)}catch(e){Ne(e,t,n+" hook")}t._hasHookEvent&&t.$emit("hook:"+n),ae()}var gt=[],_t=[],bt={},wt=!1,kt=!1,St=0;function Ot(){var e,t;for(kt=!0,gt.sort(function(e,t){return e.id-t.id}),St=0;St<gt.length;St++)t=(e=gt[St]).id,bt[t]=null,e.run();var n=_t.slice(),r=gt.slice();St=gt.length=_t.length=0,wt=kt=!(bt={}),function(e){for(var t=0;t<e.length;t++)e[t]._inactive=!0,mt(e[t],!0)}(n),function(e){var t=e.length;for(;t--;){var n=e[t],r=n.vm;r._watcher===n&&r._isMounted&&yt(r,"updated")}}(r),Z&&T.devtools&&Z.emit("flush")}var Ct=0,xt=function(e,t,n,r,o){this.vm=e,o&&(e._watcher=this),e._watchers.push(this),r?(this.deep=!!r.deep,this.user=!!r.user,this.lazy=!!r.lazy,this.sync=!!r.sync):this.deep=this.user=this.lazy=this.sync=!1,this.cb=n,this.id=++Ct,this.active=!0,this.dirty=this.lazy,this.deps=[],this.newDeps=[],this.depIds=new Q,this.newDepIds=new Q,this.expression="","function"==typeof t?this.getter=t:(this.getter=function(e){if(!P.test(e)){var n=e.split(".");return function(e){for(var t=0;t<n.length;t++){if(!e)return;e=e[n[t]]}return e}}}(t),this.getter||(this.getter=function(){})),this.value=this.lazy?void 0:this.get()};xt.prototype.get=function(){var e;ie(this);var t=this.vm;try{e=this.getter.call(t,t)}catch(e){if(!this.user)throw e;Ne(e,t,'getter for watcher "'+this.expression+'"')}finally{this.deep&&Xe(e),ae(),this.cleanupDeps()}return e},xt.prototype.addDep=function(e){var t=e.id;this.newDepIds.has(t)||(this.newDepIds.add(t),this.newDeps.push(e),this.depIds.has(t)||e.addSub(this))},xt.prototype.cleanupDeps=function(){for(var e=this.deps.length;e--;){var t=this.deps[e];this.newDepIds.has(t.id)||t.removeSub(this)}var n=this.depIds;this.depIds=this.newDepIds,this.newDepIds=n,this.newDepIds.clear(),n=this.deps,this.deps=this.newDeps,this.newDeps=n,this.newDeps.length=0},xt.prototype.update=function(){this.lazy?this.dirty=!0:this.sync?this.run():function(e){var t=e.id;if(null==bt[t]){if(bt[t]=!0,kt){for(var n=gt.length-1;St<n&>[n].id>e.id;)n--;gt.splice(n+1,0,e)}else gt.push(e);wt||(wt=!0,ze(Ot))}}(this)},xt.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||b(e)||this.deep){var t=this.value;if(this.value=e,this.user)try{this.cb.call(this.vm,e,t)}catch(e){Ne(e,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,e,t)}}},xt.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},xt.prototype.depend=function(){for(var e=this.deps.length;e--;)this.deps[e].depend()},xt.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||l(this.vm._watchers,this);for(var e=this.deps.length;e--;)this.deps[e].removeSub(this);this.active=!1}};var Et={enumerable:!0,configurable:!0,get:R,set:R};function $t(e,t,n){Et.get=function(){return this[t][n]},Et.set=function(e){this[t][n]=e},Object.defineProperty(e,n,Et)}function At(e){e._watchers=[];var t=e.$options;t.props&&function(n,r){var o=n.$options.propsData||{},i=n._props={},a=n.$options._propKeys=[];n.$parent&&me(!1);var e=function(e){a.push(e);var t=Me(e,r,o,n);we(i,e,t),e in n||$t(n,"_props",e)};for(var t in r)e(t);me(!0)}(e,t.props),t.methods&&function(e,t){e.$options.props;for(var n in t)e[n]=null==t[n]?R:y(t[n],e)}(e,t.methods),t.data?function(e){var t=e.$options.data;u(t=e._data="function"==typeof t?jt(t,e):t||{})||(t={});var n=Object.keys(t),r=e.$options.props,o=(e.$options.methods,n.length);for(;o--;){var i=n[o];r&&f(r,i)||(void 0,36!==(a=(i+"").charCodeAt(0))&&95!==a&&$t(e,"_data",i))}var a;be(t,!0)}(e):be(e._data={},!0),t.computed&&function(e,t){var n=e._computedWatchers=Object.create(null),r=K();for(var o in t){var i=t[o],a="function"==typeof i?i:i.get;r||(n[o]=new xt(e,a||R,R,It)),o in e||Mt(e,o,i)}}(e,t.computed),t.watch&&t.watch!==X&&function(e,t){for(var n in t){var r=t[n];if(Array.isArray(r))for(var o=0;o<r.length;o++)Ft(e,n,r[o]);else Ft(e,n,r)}}(e,t.watch)}function jt(e,t){ie();try{return e.call(t,t)}catch(e){return Ne(e,t,"data()"),{}}finally{ae()}}var It={lazy:!0};function Mt(e,t,n){var r=!K();Et.set="function"==typeof n?(Et.get=r?Tt(t):n,R):(Et.get=n.get?r&&!1!==n.cache?Tt(t):n.get:R,n.set?n.set:R),Object.defineProperty(e,t,Et)}function Tt(t){return function(){var e=this._computedWatchers&&this._computedWatchers[t];if(e)return e.dirty&&e.evaluate(),re.target&&e.depend(),e.value}}function Ft(e,t,n,r){return u(n)&&(n=(r=n).handler),"string"==typeof n&&(n=e[n]),e.$watch(t,n,r)}function Pt(e){var t=e.$options.provide;t&&(e._provided="function"==typeof t?t.call(e):t)}function Nt(t){var n=Rt(t.$options.inject,t);n&&(me(!1),Object.keys(n).forEach(function(e){we(t,e,n[e])}),me(!0))}function Rt(t,e){if(t){for(var n=Object.create(null),r=ee?Reflect.ownKeys(t).filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}):Object.keys(t),o=0;o<r.length;o++){for(var i=r[o],a=t[i].from,s=e;s;){if(s._provided&&f(s._provided,a)){n[i]=s._provided[a];break}s=s.$parent}if(!s&&"default"in t[i]){var c=t[i].default;n[i]="function"==typeof c?c.call(e):c}}return n}}function Dt(e,t){var n,r,o,i,a;if(Array.isArray(e)||"string"==typeof e)for(n=new Array(e.length),r=0,o=e.length;r<o;r++)n[r]=t(e[r],r);else if("number"==typeof e)for(n=new Array(e),r=0;r<e;r++)n[r]=t(r+1,r);else if(b(e))for(i=Object.keys(e),n=new Array(i.length),r=0,o=i.length;r<o;r++)a=i[r],n[r]=t(e[a],a,r);return A(n)&&(n._isVList=!0),n}function Vt(e,t,n,r){var o,i=this.$scopedSlots[e];if(i)n=n||{},r&&(n=N(N({},r),n)),o=i(n)||t;else{var a=this.$slots[e];a&&(a._rendered=!0),o=a||t}var s=n&&n.slot;return s?this.$createElement("template",{slot:s},o):o}function Lt(e){return Ie(this.$options,"filters",e)||S}function Jt(e,t){return Array.isArray(e)?-1===e.indexOf(t):e!==t}function Wt(e,t,n,r,o){var i=T.keyCodes[t]||n;return o&&r&&!T.keyCodes[t]?Jt(o,r):i?Jt(i,e):r?w(r)!==t:void 0}function qt(n,r,o,i,a){if(o)if(b(o)){var s;Array.isArray(o)&&(o=function(e){for(var t={},n=0;n<e.length;n++)e[n]&&N(t,e[n]);return t}(o));var e=function(t){if("class"===t||"style"===t||c(t))s=n;else{var e=n.attrs&&n.attrs.type;s=i||T.mustUseProp(r,e,t)?n.domProps||(n.domProps={}):n.attrs||(n.attrs={})}t in s||(s[t]=o[t],a&&((n.on||(n.on={}))["update:"+t]=function(e){o[t]=e}))};for(var t in o)e(t)}else;return n}function Bt(e,t){var n=this._staticTrees||(this._staticTrees=[]),r=n[e];return r&&!t||zt(r=n[e]=this.$options.staticRenderFns[e].call(this._renderProxy,null,this),"__static__"+e,!1),r}function Ut(e,t,n){return zt(e,"__once__"+t+(n?"_"+n:""),!0),e}function zt(e,t,n){if(Array.isArray(e))for(var r=0;r<e.length;r++)e[r]&&"string"!=typeof e[r]&&Ht(e[r],t+"_"+r,n);else Ht(e,t,n)}function Ht(e,t,n){e.isStatic=!0,e.key=t,e.isOnce=n}function Xt(e,t){if(t)if(u(t)){var n=e.on=e.on?N({},e.on):{};for(var r in t){var o=n[r],i=t[r];n[r]=o?[].concat(o,i):i}}else;return e}function Gt(e){e._o=Ut,e._n=n,e._s=t,e._l=Dt,e._t=Vt,e._q=O,e._i=C,e._m=Bt,e._f=Lt,e._k=Wt,e._b=qt,e._v=ue,e._e=le,e._u=pt,e._g=Xt}function Kt(e,t,n,i,r){var a,s=r.options;f(i,"_uid")?(a=Object.create(i))._original=i:i=(a=i)._original;var o=j(s._compiled),c=!o;this.data=e,this.props=t,this.children=n,this.parent=i,this.listeners=e.on||_,this.injections=Rt(s.inject,i),this.slots=function(){return ut(n,i)},o&&(this.$options=s,this.$slots=this.slots(),this.$scopedSlots=e.scopedSlots||_),s._scopeId?this._c=function(e,t,n,r){var o=mn(a,e,t,n,r,c);return o&&!Array.isArray(o)&&(o.fnScopeId=s._scopeId,o.fnContext=i),o}:this._c=function(e,t,n,r){return mn(a,e,t,n,r,c)}}function Zt(e,t,n,r){var o=fe(e);return o.fnContext=n,o.fnOptions=r,t.slot&&((o.data||(o.data={})).slot=t.slot),o}function Yt(e,t){for(var n in t)e[h(n)]=t[n]}Gt(Kt.prototype);var Qt="@inRecycleList";function en(e,t,n,r){if(o&&o.taskCenter)return"function"==typeof o.taskCenter.registerHook?o.taskCenter.registerHook(e,t,n,r):void 0}function tn(e,n,t){if(b(n))if(t)e.$refs={};else{var r=e.$refs||{};Object.keys(n).forEach(function(e){var t=n[e];r[e]=1===t.length?t[0]:t}),e.$refs=r}}function nn(e,n,r,t){if(b(r)){var o=e.$refs||{};t?Object.keys(r).forEach(function(e){var t=r[e];o[e]&&(1===t.length&&Array.isArray(o[e])?delete o[e][n]:delete o[e])}):(Object.keys(r).forEach(function(e){var t=r[e];1===t.length?(Array.isArray(o[e])||(o[e]=[]),o[e][n]=t[0]):o[e]=t}),e.$refs=o)}}var rn=0;function on(e){var t=e.$options.data,n=e.$options.computed||{},r=e._data?Object.assign({},e._data):"function"==typeof t?jt(t,e):t||{},o={};for(var i in n)o[i]=e[i];return Object.assign({},r,o)}function an(e){void 0===e&&(e={});var r=this,t=e.componentId;F(r,"_vmTemplate",e.vmTemplate),r._uid=t||"virtual-component-"+rn++,r._isVue=!0,e&&e._isComponent?xn(r,e):r.$options=je(En(r.constructor),e||{},r),ht((r._renderProxy=r)._self=r),at(r),yn(r),yt(r,"beforeCreate"),Nt(r),At(r),Pt(r),yt(r,"created"),en(t,"lifecycle","attach",function(e){tn(r,e&&e.refs),yt(r,"beforeMount"),new xt(r,function(){return on(r)},function(){return r._update(r._vnode,!1)}),r._isMounted=!0,yt(r,"mounted")}),en(t,"lifecycle","update",function(e){tn(r,e&&e.refs),r._update(r._vnode,!1)}),en(t,"lifecycle","syncState",function(e,t){if(u(t))for(var n in t)r[n]=t[n];return on(r)}),en(t,"lifecycle","detach",function(e){tn(r,e&&e.refs,!0),r.$destroy(),r._vmTemplate&&(r._vmTemplate.removeVirtualComponent(r._uid),delete r._vmTemplate)})}function sn(e){var t=this,n=t.$options.componentId;(t._isMounted&&yt(t,"beforeUpdate"),t._vnode=e,t._isMounted&&n)&&function(e,t,n){if(o&&o.taskCenter)"function"==typeof o.taskCenter.updateData&&o.taskCenter.updateData(e,t,n)}(n,on(t),function(){yt(t,"updated")})}function cn(e){void 0===e&&(e={});var t=this;t._uid="virtual-component-template-"+rn++,t._isVue=!0,e&&e._isComponent?xn(t,e):t.$options=je(En(t.constructor),e||{},t),at(t._self=t),yn(t),At(t),this.registerVirtualComponent()}function ln(e){var t,n,o,i;delete e.data.attrs[Qt],n=(t=e).componentOptions.Ctor,o=n.extend({}),i=o.prototype.$emit,o.prototype._init=an,o.prototype._update=sn,o.prototype.$emit=function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];var r=this._uid,o=this._vmTemplate;return r&&o&&(t.push(r),i.apply(o,t)),i.apply(this,t)},t.componentOptions.Ctor=n.extend({methods:{registerVirtualComponent:function(){var r=this;F(r,"_virtualComponents",{}),en(String(r._uid),"lifecycle","create",function(e,t){var n=new o({vmTemplate:r,componentId:e,propsData:t});return n._uid=e,r._virtualComponents&&(r._virtualComponents[e]=n),on(n)})},removeVirtualComponent:function(e){delete this._virtualComponents[e]}},destroyed:function(){delete this._virtualComponents}}),t.componentOptions.Ctor.prototype._init=cn,t.componentOptions.Ctor.prototype._update=R;var r=dn(e),a=r.$options["@render"];if(a)try{return a.call(r)}catch(e){Ne(e,r,"@render")}}var un={init:function(e,t,n,r){if(e.componentInstance&&!e.componentInstance._isDestroyed&&e.data.keepAlive){var o=e;un.prepatch(o,o)}else{(e.componentInstance=dn(e,dt,n,r)).$mount(t?e.elm:void 0,t)}},prepatch:function(e,t){var n=t.componentOptions;!function(e,t,n,r,o){var i=!!(o||e.$options._renderChildren||r.data.scopedSlots||e.$scopedSlots!==_);if(e.$options._parentVnode=r,e.$vnode=r,e._vnode&&(e._vnode.parent=r),e.$options._renderChildren=o,e.$attrs=r.data.attrs||_,e.$listeners=n||_,t&&e.$options.props){me(!1);for(var a=e._props,s=e.$options._propKeys||[],c=0;c<s.length;c++){var l=s[c],u=e.$options.props;a[l]=Me(l,u,t,e)}me(!0),e.$options.propsData=t}n=n||_;var f=e.$options._parentListeners;e.$options._parentListeners=n,lt(e,n,f),i&&(e.$slots=ut(o,r.context),e.$forceUpdate())}(t.componentInstance=e.componentInstance,n.propsData,n.listeners,t,n.children)},insert:function(e){var t,n=e.context,r=e.componentInstance;r._isMounted||(r._isMounted=!0,yt(r,"mounted")),e.data.keepAlive&&(n._isMounted?((t=r)._inactive=!1,_t.push(t)):mt(r,!0))},destroy:function(e){var t=e.componentInstance;t._isDestroyed||(e.data.keepAlive?function e(t,n){if(!(n&&(t._directInactive=!0,vt(t))||t._inactive)){t._inactive=!0;for(var r=0;r<t.$children.length;r++)e(t.$children[r]);yt(t,"deactivated")}}(t,!0):t.$destroy())}},fn=Object.keys(un);function pn(e,t,n,r,o){if(!$(e)){var i=n.$options._base;if(b(e)&&(e=i.extend(e)),"function"==typeof e){var a,s,c,l,u,f,p;if($(e.cid)&&void 0===(e=function(t,n,e){if(j(t.error)&&A(t.errorComp))return t.errorComp;if(A(t.resolved))return t.resolved;if(j(t.loading)&&A(t.loadingComp))return t.loadingComp;if(!A(t.contexts)){var r=t.contexts=[e],o=!0,i=function(){for(var e=0,t=r.length;e<t;e++)r[e].$forceUpdate()},a=D(function(e){t.resolved=rt(e,n),o||i()}),s=D(function(e){A(t.errorComp)&&(t.error=!0,i())}),c=t(a,s);return b(c)&&("function"==typeof c.then?$(t.resolved)&&c.then(a,s):A(c.component)&&"function"==typeof c.component.then&&(c.component.then(a,s),A(c.error)&&(t.errorComp=rt(c.error,n)),A(c.loading)&&(t.loadingComp=rt(c.loading,n),0===c.delay?t.loading=!0:setTimeout(function(){$(t.resolved)&&$(t.error)&&(t.loading=!0,i())},c.delay||200)),A(c.timeout)&&setTimeout(function(){$(t.resolved)&&s(null)},c.timeout))),o=!1,t.loading?t.loadingComp:t.resolved}t.contexts.push(e)}(a=e,i,n)))return s=a,c=t,l=n,u=r,f=o,(p=le()).asyncFactory=s,p.asyncMeta={data:c,context:l,children:u,tag:f},p;t=t||{},En(e),A(t.model)&&function(e,t){var n=e.model&&e.model.prop||"value",r=e.model&&e.model.event||"input";(t.props||(t.props={}))[n]=t.model.value;var o=t.on||(t.on={});A(o[r])?o[r]=[t.model.callback].concat(o[r]):o[r]=t.model.callback}(e.options,t);var d=function(e,t,n){var r=t.options.props;if(!$(r)){var o={},i=e.attrs,a=e.props;if(A(i)||A(a))for(var s in r){var c=w(s);et(o,a,s,c,!0)||et(o,i,s,c,!1)}return o}}(t,e);if(j(e.options.functional))return function(e,t,n,r,o){var i=e.options,a={},s=i.props;if(A(s))for(var c in s)a[c]=Me(c,s,t||_);else A(n.attrs)&&Yt(a,n.attrs),A(n.props)&&Yt(a,n.props);var l=new Kt(n,a,o,r,e),u=i.render.call(null,l._c,l);if(u instanceof se)return Zt(u,n,l.parent,i);if(Array.isArray(u)){for(var f=tt(u)||[],p=new Array(f.length),d=0;d<f.length;d++)p[d]=Zt(f[d],n,l.parent,i);return p}}(e,d,t,n,r);var h=t.on;if(t.on=t.nativeOn,j(e.options.abstract)){var v=t.slot;t={},v&&(t.slot=v)}!function(e){for(var t=e.hook||(e.hook={}),n=0;n<fn.length;n++){var r=fn[n];t[r]=un[r]}}(t);var m,y=e.options.name||o,g=new se("vue-component-"+e.cid+(y?"-"+y:""),t,void 0,void 0,void 0,n,{Ctor:e,propsData:d,listeners:h,tag:o,children:r},a);return(m=g).data.attrs&&Qt in m.data.attrs?ln(g):g}}}function dn(e,t,n,r){var o={_isComponent:!0,parent:t,_parentVnode:e,_parentElm:n||null,_refElm:r||null},i=e.data.inlineTemplate;return A(i)&&(o.render=i.render,o.staticRenderFns=i.staticRenderFns),new e.componentOptions.Ctor(o)}var hn=1,vn=2;function mn(e,t,n,r,o,i){return(Array.isArray(n)||I(n))&&(o=r,r=n,n=void 0),j(i)&&(o=vn),function(e,t,n,r,o){if(A(n)&&A(n.__ob__))return le();A(n)&&A(n.is)&&(t=n.is);if(!t)return le();Array.isArray(r)&&"function"==typeof r[0]&&((n=n||{}).scopedSlots={default:r[0]},r.length=0);o===vn?r=tt(r):o===hn&&(r=function(e){for(var t=0;t<e.length;t++)if(Array.isArray(e[t]))return Array.prototype.concat.apply([],e);return e}(r));var i,a;if("string"==typeof t){var s;a=e.$vnode&&e.$vnode.ns||T.getTagNamespace(t),i=T.isReservedTag(t)?new se(T.parsePlatformTagName(t),n,r,void 0,void 0,e):A(s=Ie(e.$options,"components",t))?pn(s,n,e,r,t):new se(t,n,r,void 0,void 0,e)}else i=pn(t,n,e,r);return Array.isArray(i)?i:A(i)?(A(a)&&function e(t,n,r){t.ns=n;"foreignObject"===t.tag&&(r=!(n=void 0));if(A(t.children))for(var o=0,i=t.children.length;o<i;o++){var a=t.children[o];A(a.tag)&&($(a.ns)||j(r)&&"svg"!==a.tag)&&e(a,n,r)}}(i,a),A(n)&&function(e){b(e.style)&&Xe(e.style);b(e.class)&&Xe(e.class)}(n),i):le()}(e,t,n,r,o)}function yn(o){o._vnode=null,o._staticTrees=null;var e=o.$options,t=o.$vnode=e._parentVnode,n=t&&t.context;o.$slots=ut(e._renderChildren,n),o.$scopedSlots=_,o._c=function(e,t,n,r){return mn(o,e,t,n,r,!1)},o.$createElement=function(e,t,n,r){return mn(o,e,t,n,r,!0)};var r=t&&t.data;we(o,"$attrs",r&&r.attrs||_,null,!0),we(o,"$listeners",e._parentListeners||_,null,!0)}var gn,_n,bn,wn,kn,Sn,On,Cn=0;function xn(e,t){var n=e.$options=Object.create(e.constructor.options),r=t._parentVnode;n.parent=t.parent,n._parentVnode=r,n._parentElm=t._parentElm,n._refElm=t._refElm;var o=r.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,t.render&&(n.render=t.render,n.staticRenderFns=t.staticRenderFns)}function En(e){var t=e.options;if(e.super){var n=En(e.super);if(n!==e.superOptions){e.superOptions=n;var r=function(e){var t,n=e.options,r=e.extendOptions,o=e.sealedOptions;for(var i in n)n[i]!==o[i]&&(t||(t={}),t[i]=$n(n[i],r[i],o[i]));return t}(e);r&&N(e.extendOptions,r),(t=e.options=je(n,e.extendOptions)).name&&(t.components[t.name]=e)}}return t}function $n(e,t,n){if(Array.isArray(e)){var r=[];n=Array.isArray(n)?n:[n],t=Array.isArray(t)?t:[t];for(var o=0;o<e.length;o++)(0<=t.indexOf(e[o])||n.indexOf(e[o])<0)&&r.push(e[o]);return r}return e}function An(e){this._init(e)}function jn(e){e.cid=0;var a=1;e.extend=function(e){e=e||{};var t=this,n=t.cid,r=e._Ctor||(e._Ctor={});if(r[n])return r[n];var o=e.name||t.options.name,i=function(e){this._init(e)};return((i.prototype=Object.create(t.prototype)).constructor=i).cid=a++,i.options=je(t.options,e),i.super=t,i.options.props&&function(e){var t=e.options.props;for(var n in t)$t(e.prototype,"_props",n)}(i),i.options.computed&&function(e){var t=e.options.computed;for(var n in t)Mt(e.prototype,n,t[n])}(i),i.extend=t.extend,i.mixin=t.mixin,i.use=t.use,x.forEach(function(e){i[e]=t[e]}),o&&(i.options.components[o]=i),i.superOptions=t.options,i.extendOptions=e,i.sealedOptions=N({},i.options),r[n]=i}}function In(e){return e&&(e.Ctor.options.name||e.tag)}function Mn(e,t){return Array.isArray(e)?-1<e.indexOf(t):"string"==typeof e?-1<e.split(",").indexOf(t):(n=e,"[object RegExp]"===r.call(n)&&e.test(t));var n}function Tn(e,t){var n=e.cache,r=e.keys,o=e._vnode;for(var i in n){var a=n[i];if(a){var s=In(a.componentOptions);s&&!t(s)&&Fn(n,i,r,o)}}}function Fn(e,t,n,r){var o=e[t];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),e[t]=null,l(n,t)}An.prototype._init=function(e){var t=this;t._uid=Cn++,t._isVue=!0,e&&e._isComponent?xn(t,e):t.$options=je(En(t.constructor),e||{},t),ht((t._renderProxy=t)._self=t),at(t),yn(t),yt(t,"beforeCreate"),Nt(t),At(t),Pt(t),yt(t,"created"),t.$options.el&&t.$mount(t.$options.el)},gn=An,_n={get:function(){return this._data}},bn={get:function(){return this._props}},Object.defineProperty(gn.prototype,"$data",_n),Object.defineProperty(gn.prototype,"$props",bn),gn.prototype.$set=ke,gn.prototype.$delete=Se,gn.prototype.$watch=function(e,t,n){if(u(t))return Ft(this,e,t,n);(n=n||{}).user=!0;var r=new xt(this,e,t,n);return n.immediate&&t.call(this,r.value),function(){r.teardown()}},kn=/^hook:/,(wn=An).prototype.$on=function(e,t){if(Array.isArray(e))for(var n=0,r=e.length;n<r;n++)this.$on(e[n],t);else(this._events[e]||(this._events[e]=[])).push(t),kn.test(e)&&(this._hasHookEvent=!0);return this},wn.prototype.$once=function(e,t){var n=this;function r(){n.$off(e,r),t.apply(n,arguments)}return r.fn=t,n.$on(e,r),n},wn.prototype.$off=function(e,t){var n=this;if(!arguments.length)return n._events=Object.create(null),n;if(Array.isArray(e)){for(var r=0,o=e.length;r<o;r++)this.$off(e[r],t);return n}var i=n._events[e];if(!i)return n;if(!t)return n._events[e]=null,n;if(t)for(var a,s=i.length;s--;)if((a=i[s])===t||a.fn===t){i.splice(s,1);break}return n},wn.prototype.$emit=function(t){var n=this,e=n._events[t];if(e){e=1<e.length?g(e):e;for(var r=g(arguments,1),o=0,i=e.length;o<i;o++)try{e[o].apply(n,r)}catch(e){Ne(e,n,'event handler for "'+t+'"')}}return n},(Sn=An).prototype._update=function(e,t){var n=this;n._isMounted&&yt(n,"beforeUpdate");var r=n.$el,o=n._vnode,i=dt;(dt=n)._vnode=e,o?n.$el=n.__patch__(o,e):(n.$el=n.__patch__(n.$el,e,t,!1,n.$options._parentElm,n.$options._refElm),n.$options._parentElm=n.$options._refElm=null),dt=i,r&&(r.__vue__=null),n.$el&&(n.$el.__vue__=n),n.$vnode&&n.$parent&&n.$vnode===n.$parent._vnode&&(n.$parent.$el=n.$el)},Sn.prototype.$forceUpdate=function(){this._watcher&&this._watcher.update()},Sn.prototype.$destroy=function(){var e=this;if(!e._isBeingDestroyed){yt(e,"beforeDestroy"),e._isBeingDestroyed=!0;var t=e.$parent;!t||t._isBeingDestroyed||e.$options.abstract||l(t.$children,e),e._watcher&&e._watcher.teardown();for(var n=e._watchers.length;n--;)e._watchers[n].teardown();e._data.__ob__&&e._data.__ob__.vmCount--,e._isDestroyed=!0,e.__patch__(e._vnode,null),yt(e,"destroyed"),e.$off(),e.$el&&(e.$el.__vue__=null),e.$vnode&&(e.$vnode.parent=null)}},Gt((On=An).prototype),On.prototype.$nextTick=function(e){return ze(e,this)},On.prototype._render=function(){var t,n=this,e=n.$options,r=e.render,o=e._parentVnode;o&&(n.$scopedSlots=o.data.scopedSlots||_),n.$vnode=o;try{t=r.call(n._renderProxy,n.$createElement)}catch(e){Ne(e,n,"render"),t=n._vnode}return t instanceof se||(t=le()),t.parent=o,t};var Pn,Nn,Rn,Dn=[String,RegExp,Array],Vn={KeepAlive:{name:"keep-alive",abstract:!0,props:{include:Dn,exclude:Dn,max:[String,Number]},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var e in this.cache)Fn(this.cache,e,this.keys)},mounted:function(){var e=this;this.$watch("include",function(t){Tn(e,function(e){return Mn(t,e)})}),this.$watch("exclude",function(t){Tn(e,function(e){return!Mn(t,e)})})},render:function(){var e=this.$slots.default,t=it(e),n=t&&t.componentOptions;if(n){var r=In(n),o=this.include,i=this.exclude;if(o&&(!r||!Mn(o,r))||i&&r&&Mn(i,r))return t;var a=this.cache,s=this.keys,c=null==t.key?n.Ctor.cid+(n.tag?"::"+n.tag:""):t.key;a[c]?(t.componentInstance=a[c].componentInstance,l(s,c),s.push(c)):(a[c]=t,s.push(c),this.max&&s.length>parseInt(this.max)&&Fn(a,s[0],s,this._vnode)),t.data.keepAlive=!0}return t||e&&e[0]}}};Pn=An,Rn={get:function(){return T}},Object.defineProperty(Pn,"config",Rn),Pn.util={warn:te,extend:N,mergeOptions:je,defineReactive:we},Pn.set=ke,Pn.delete=Se,Pn.nextTick=ze,Pn.options=Object.create(null),x.forEach(function(e){Pn.options[e+"s"]=Object.create(null)}),N((Pn.options._base=Pn).options.components,Vn),Pn.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(-1<t.indexOf(e))return this;var n=g(arguments,1);return n.unshift(this),"function"==typeof e.install?e.install.apply(e,n):"function"==typeof e&&e.apply(null,n),t.push(e),this},Pn.mixin=function(e){return this.options=je(this.options,e),this},jn(Pn),Nn=Pn,x.forEach(function(n){Nn[n]=function(e,t){return t?("component"===n&&u(t)&&(t.name=t.name||e,t=this.options._base.extend(t)),"directive"===n&&"function"==typeof t&&(t={bind:t,update:t}),this.options[n+"s"][e]=t):this.options[n+"s"][e]}}),Object.defineProperty(An.prototype,"$isServer",{get:K}),Object.defineProperty(An.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(An,"FunctionalRenderContext",{value:Kt}),An.version="2.5.16";var Ln=1;function Jn(e){this.instanceId="",this.nodeId=Ln++,this.parentNode=null,this.nodeType=3,this.text=e}function Wn(e){return o.createElement(e)}var qn=Object.freeze({namespaceMap:{},createElement:Wn,createElementNS:function(e,t){return o.createElement(e+":"+t)},createTextNode:function(e){return new Jn(e)},createComment:function(e){return o.createComment(e)},insertBefore:function(e,t,n){if(3!==t.nodeType)e.insertBefore(t,n);else if("text"===e.type)e.setAttr("value",t.text),t.parentNode=e;else{var r=Wn("text");r.setAttr("value",t.text),e.insertBefore(r,n)}},removeChild:function(e,t){3!==t.nodeType?e.removeChild(t):e.setAttr("value","")},appendChild:function(e,t){if(3!==t.nodeType)e.appendChild(t);else if("text"===e.type)e.setAttr("value",t.text),t.parentNode=e;else{var n=Wn("text");n.setAttr("value",t.text),e.appendChild(n)}},parentNode:function(e){return e.parentNode},nextSibling:function(e){return e.nextSibling},tagName:function(e){return e.type},setTextContent:function(e,t){e.parentNode&&e.parentNode.setAttr("value",t)},setAttribute:function(e,t,n){e.setAttr(t,n)},setStyleScope:function(e,t){e.setAttr("@styleScope",t)}}),Bn={create:function(e,t){Un(t)},update:function(e,t){e.data.ref!==t.data.ref&&(Un(e,!0),Un(t))},destroy:function(e){Un(e,!0)}};function Un(e,t){var n=e.data.ref;if(A(n)){var r=e.context,o=e.componentInstance||e.elm,i=r.$refs;t?Array.isArray(i[n])?l(i[n],o):i[n]===o&&(i[n]=void 0):e.data.refInFor?Array.isArray(i[n])?i[n].indexOf(o)<0&&i[n].push(o):i[n]=[o]:i[n]=o}}s("html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,menuitem,summary,content,element,shadow,template,blockquote,iframe,tfoot"),s("svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view",!0);var zn=s("text,number,password,search,email,tel,url"),Hn=new se("",{},[]),Xn=["create","activate","update","remove","destroy"];function Gn(e,t){return e.key===t.key&&(e.tag===t.tag&&e.isComment===t.isComment&&A(e.data)===A(t.data)&&function(e,t){if("input"!==e.tag)return!0;var n,r=A(n=e.data)&&A(n=n.attrs)&&n.type,o=A(n=t.data)&&A(n=n.attrs)&&n.type;return r===o||zn(r)&&zn(o)}(e,t)||j(e.isAsyncPlaceholder)&&e.asyncFactory===t.asyncFactory&&$(t.asyncFactory.error))}function Kn(e,t,n){var r,o,i={};for(r=t;r<=n;++r)A(o=e[r].key)&&(i[o]=r);return i}var Zn={create:Yn,update:Yn,destroy:function(e){Yn(e,Hn)}};function Yn(e,t){(e.data.directives||t.data.directives)&&function(t,n){var e,r,o,i=t===Hn,a=n===Hn,s=er(t.data.directives,t.context),c=er(n.data.directives,n.context),l=[],u=[];for(e in c)r=s[e],o=c[e],r?(o.oldValue=r.value,tr(o,"update",n,t),o.def&&o.def.componentUpdated&&u.push(o)):(tr(o,"bind",n,t),o.def&&o.def.inserted&&l.push(o));if(l.length){var f=function(){for(var e=0;e<l.length;e++)tr(l[e],"inserted",n,t)};i?Qe(n,"insert",f):f()}u.length&&Qe(n,"postpatch",function(){for(var e=0;e<u.length;e++)tr(u[e],"componentUpdated",n,t)});if(!i)for(e in s)c[e]||tr(s[e],"unbind",t,t,a)}(e,t)}var Qn=Object.create(null);function er(e,t){var n,r,o,i=Object.create(null);if(!e)return i;for(n=0;n<e.length;n++)(r=e[n]).modifiers||(r.modifiers=Qn),(i[(o=r,o.rawName||o.name+"."+Object.keys(o.modifiers||{}).join("."))]=r).def=Ie(t.$options,"directives",r.name);return i}function tr(t,n,r,e,o){var i=t.def&&t.def[n];if(i)try{i(r.elm,t,r,e,o)}catch(e){Ne(e,r.context,"directive "+t.name+" "+n+" hook")}}var nr=[Bn,Zn];function rr(e,t){if(e.data.attrs||t.data.attrs){var n,r,o=t.elm,i=e.data.attrs||{},a=t.data.attrs||{};a.__ob__&&(a=t.data.attrs=N({},a));var s="function"==typeof o.setAttrs,c={};for(n in a)r=a[n],i[n]!==r&&(s?c[n]=r:o.setAttr(n,r));for(n in i)null==a[n]&&(s?c[n]=void 0:o.setAttr(n));s&&o.setAttrs(c)}}var or={create:rr,update:rr};function ir(e,t){var n=t.elm,r=t.context,o=t.data,i=e.data;if(o.staticClass||o.class||i&&(i.staticClass||i.class)){var a=[],s=i.staticClass;s&&a.push.apply(a,s),i.class&&a.push.apply(a,i.class);var c,l,u,f,p=[],d=o.staticClass;if(d&&p.push.apply(p,d),o.class&&p.push.apply(p,o.class),"function"==typeof n.setClassList)n.setClassList(p);else{var h=(c=a,l=p,u=r.$options.style||{},f={},l.forEach(function(e){var t=u[e];N(f,t)}),c.forEach(function(e){var t=u[e];for(var n in t)f.hasOwnProperty(n)||(f[n]="")}),f);if("function"==typeof n.setStyles)n.setStyles(h);else for(var v in h)n.setStyle(v,h[v])}}}var ar,sr,cr={create:ir,update:ir};function lr(t,e,n,r,o,i){if(r)console.log("Weex do not support event in bubble phase.");else{if(n){var a=e,s=ar;e=function(e){null!==(1===arguments.length?a(e):a.apply(null,arguments))&&ur(t,null,null,s)}}if(sr&&sr._virtualComponents){ar._context=sr;var c=e;e=function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];var r=(t[0]||{}).componentId,o=this._context;r&&this._context&&(o=(this._context._virtualComponents||{})[r]||o);try{!function(e,t,n){void 0===n&&(n=null);var r=e.fns;if(!Array.isArray(r))return"function"==typeof r?r.apply(n,t):e.apply(n,t);for(var o=r.slice(),i=0;i<o.length;i++)o[i].apply(n,t)}(c,t,o)}catch(e){Ne(e,o,"Failed to invoke virtual component handler ("+r+")")}}}ar.addEvent(t,e,i)}}function ur(e,t,n,r){(r||ar).removeEvent(e)}function fr(e,t){if(e.data.on||t.data.on){var n=t.data.on||{},r=e.data.on||{};ar=t.elm,sr=t.context,Ye(n,r,lr,ur,t.context),sr=ar=void 0}}var pr={create:fr,update:fr},dr=p(h);function hr(e,t){if(e.data.style||t.data.style){var n,r,o=t.elm,i=e.data.style||{},a=t.data.style||{},s=a.__ob__;Array.isArray(a)&&(a=t.data.style=function(e){for(var t={},n=0;n<e.length;n++)e[n]&&N(t,e[n]);return t}(a)),s&&(a=t.data.style=N({},a));var c="function"==typeof o.setStyles,l={};for(r in i)a[r]||(c?l[dr(r)]="":o.setStyle(dr(r),""));for(r in a)n=a[r],c?l[dr(r)]=n:o.setStyle(dr(r),n);c&&o.setStyles(l)}}var vr={create:function(e,t){if(t.data.staticStyle){var n=t.elm,r=t.data.staticStyle,o="function"==typeof n.setStyles,i={};for(var a in r)r[a]&&(o?i[dr(a)]=r[a]:n.setStyle(dr(a),r[a]));o&&n.setStyles(i),hr(e,t)}else hr(e,t)},update:hr};function mr(e){if(e){if("object"!=typeof e)return"string"==typeof e?yr(e):void 0;var t={};return!1!==e.css&&N(t,yr(e.name||"v")),N(t,e),t}}var yr=p(function(e){return{enterClass:e+"-enter",enterToClass:e+"-enter-to",enterActiveClass:e+"-enter-active",leaveClass:e+"-leave",leaveToClass:e+"-leave-to",leaveActiveClass:e+"-leave-active"}});J&&!U&&(void 0===window.ontransitionend&&window.onwebkittransitionend,void 0===window.onanimationend&&window.onwebkitanimationend);J&&window.requestAnimationFrame&&window.requestAnimationFrame.bind(window);function gr(e,n){var r=n.elm;r._leaveCb&&(r._leaveCb.cancelled=!0,r._leaveCb());var t=mr(n.data.transition);if(t&&!r._enterCb){for(var o=t.enterClass,i=t.enterToClass,a=t.enterActiveClass,s=t.appearClass,c=t.appearToClass,l=t.appearActiveClass,u=t.beforeEnter,f=t.enter,p=t.afterEnter,d=t.enterCancelled,h=t.beforeAppear,v=t.appear,m=t.afterAppear,y=t.appearCancelled,g=dt,_=dt.$vnode;_&&_.parent;)g=(_=_.parent).context;var b=!g._isMounted||!n.isRootInsert;if(!b||v||""===v){var w=b?s:o,k=b?c:i,S=b?l:a,O=b&&h||u,C=b&&"function"==typeof v?v:f,x=b&&m||p,E=b&&y||d,$=C&&1<(C._length||C.length),A=n.context.$options.style||{},j=A[w],I=A["@TRANSITION"]&&A["@TRANSITION"][S]||{},M=function(e,t,n,r,o,i){var a={},s=t[n],c=t[r],l=t[o];if(s)for(var u in s)a[u]=e.style[u];if(l)for(var f in l)0!==f.indexOf("transition")&&(a[f]=l[f]);c&&N(a,c);return a}(r,A,w,k,S,n.context),T=0<Object.keys(M).length,F=r._enterCb=D(function(){F.cancelled?E&&E(r):x&&x(r),r._enterCb=null});if(setTimeout(function(){var e=r.parentNode,t=e&&e._pending&&e._pending[n.key];(t&&t.context===n.context&&t.tag===n.tag&&t.elm._leaveCb&&t.elm._leaveCb(),C&&C(r,F),T)?n.context.$requireWeexModule("animation").transition(r.ref,{styles:M,duration:I.duration||0,delay:I.delay||0,timingFunction:I.timingFunction||"linear"},$?R:F):$||F()},16),O&&O(r),j)if("function"==typeof r.setStyles)r.setStyles(j);else for(var P in j)r.setStyle(P,j[P]);T||$||F()}}}var _r=function(e){var r,t,g={},n=e.modules,_=e.nodeOps;for(r=0;r<Xn.length;++r)for(g[Xn[r]]=[],t=0;t<n.length;++t)A(n[t][Xn[r]])&&g[Xn[r]].push(n[t][Xn[r]]);function i(e){var t=_.parentNode(e);A(t)&&_.removeChild(t,e)}function b(e,t,n,r,o,i,a){if(A(e.elm)&&A(i)&&(e=i[a]=fe(e)),e.isRootInsert=!o,!function(e,t,n,r){var o=e.data;if(A(o)){var i=A(e.componentInstance)&&o.keepAlive;if(A(o=o.hook)&&A(o=o.init)&&o(e,!1,n,r),A(e.componentInstance))return d(e,t),j(i)&&function(e,t,n,r){for(var o,i=e;i.componentInstance;)if(i=i.componentInstance._vnode,A(o=i.data)&&A(o=o.transition)){for(o=0;o<g.activate.length;++o)g.activate[o](Hn,i);t.push(i);break}f(n,e.elm,r)}(e,t,n,r),!0}}(e,t,n,r)){var s=e.data,c=e.children,l=e.tag;if(A(l)){e.elm=e.ns?_.createElementNS(e.ns,l):_.createElement(l,e),p(e);var u=A(s)&&j(s.appendAsTree);u||(A(s)&&v(e,t),f(n,e.elm,r)),h(e,c,t),u&&(A(s)&&v(e,t),f(n,e.elm,r))}else j(e.isComment)?e.elm=_.createComment(e.text):e.elm=_.createTextNode(e.text),f(n,e.elm,r)}}function d(e,t){A(e.data.pendingInsert)&&(t.push.apply(t,e.data.pendingInsert),e.data.pendingInsert=null),e.elm=e.componentInstance.$el,w(e)?(v(e,t),p(e)):(Un(e),t.push(e))}function f(e,t,n){A(e)&&(A(n)?n.parentNode===e&&_.insertBefore(e,t,n):_.appendChild(e,t))}function h(e,t,n){if(Array.isArray(t))for(var r=0;r<t.length;++r)b(t[r],n,e.elm,null,!0,t,r);else I(e.text)&&_.appendChild(e.elm,_.createTextNode(String(e.text)))}function w(e){for(;e.componentInstance;)e=e.componentInstance._vnode;return A(e.tag)}function v(e,t){for(var n=0;n<g.create.length;++n)g.create[n](Hn,e);A(r=e.data.hook)&&(A(r.create)&&r.create(Hn,e),A(r.insert)&&t.push(e))}function p(e){var t;if(A(t=e.fnScopeId))_.setStyleScope(e.elm,t);else for(var n=e;n;)A(t=n.context)&&A(t=t.$options._scopeId)&&_.setStyleScope(e.elm,t),n=n.parent;A(t=dt)&&t!==e.context&&t!==e.fnContext&&A(t=t.$options._scopeId)&&_.setStyleScope(e.elm,t)}function y(e,t,n,r,o,i){for(;r<=o;++r)b(n[r],i,e,t,!1,n,r)}function k(e){var t,n,r=e.data;if(A(r))for(A(t=r.hook)&&A(t=t.destroy)&&t(e),t=0;t<g.destroy.length;++t)g.destroy[t](e);if(A(t=e.children))for(n=0;n<e.children.length;++n)k(e.children[n])}function S(e,t,n,r){for(;n<=r;++n){var o=t[n];A(o)&&(A(o.tag)?(a(o),k(o)):i(o.elm))}}function a(e,t){if(A(t)||A(e.data)){var n,r=g.remove.length+1;for(A(t)?t.listeners+=r:t=function(e,t){function n(){0==--n.listeners&&i(e)}return n.listeners=t,n}(e.elm,r),A(n=e.componentInstance)&&A(n=n._vnode)&&A(n.data)&&a(n,t),n=0;n<g.remove.length;++n)g.remove[n](e,t);A(n=e.data.hook)&&A(n=n.remove)?n(e,t):t()}else i(e.elm)}function O(e,t,n,r){for(var o=n;o<r;o++){var i=t[o];if(A(i)&&Gn(e,i))return o}}function C(e,t,n,r){if(e!==t){var o=t.elm=e.elm;if(j(e.isAsyncPlaceholder))A(t.asyncFactory.resolved)?E(e.elm,t,n):t.isAsyncPlaceholder=!0;else if(j(t.isStatic)&&j(e.isStatic)&&t.key===e.key&&(j(t.isCloned)||j(t.isOnce)))t.componentInstance=e.componentInstance;else{var i,a=t.data;A(a)&&A(i=a.hook)&&A(i=i.prepatch)&&i(e,t);var s=e.children,c=t.children;if(A(a)&&w(t)){for(i=0;i<g.update.length;++i)g.update[i](e,t);A(i=a.hook)&&A(i=i.update)&&i(e,t)}$(t.text)?A(s)&&A(c)?s!==c&&function(e,t,n,r,o){for(var i,a,s,c=0,l=0,u=t.length-1,f=t[0],p=t[u],d=n.length-1,h=n[0],v=n[d],m=!o;c<=u&&l<=d;)$(f)?f=t[++c]:$(p)?p=t[--u]:Gn(f,h)?(C(f,h,r),f=t[++c],h=n[++l]):Gn(p,v)?(C(p,v,r),p=t[--u],v=n[--d]):Gn(f,v)?(C(f,v,r),m&&_.insertBefore(e,f.elm,_.nextSibling(p.elm)),f=t[++c],v=n[--d]):(Gn(p,h)?(C(p,h,r),m&&_.insertBefore(e,p.elm,f.elm),p=t[--u]):($(i)&&(i=Kn(t,c,u)),$(a=A(h.key)?i[h.key]:O(h,t,c,u))?b(h,r,e,f.elm,!1,n,l):Gn(s=t[a],h)?(C(s,h,r),t[a]=void 0,m&&_.insertBefore(e,s.elm,f.elm)):b(h,r,e,f.elm,!1,n,l)),h=n[++l]);u<c?y(e,$(n[d+1])?null:n[d+1].elm,n,l,d,r):d<l&&S(0,t,c,u)}(o,s,c,n,r):A(c)?(A(e.text)&&_.setTextContent(o,""),y(o,null,c,0,c.length-1,n)):A(s)?S(0,s,0,s.length-1):A(e.text)&&_.setTextContent(o,""):e.text!==t.text&&_.setTextContent(o,t.text),A(a)&&A(i=a.hook)&&A(i=i.postpatch)&&i(e,t)}}}function x(e,t,n){if(j(n)&&A(e.parent))e.parent.data.pendingInsert=t;else for(var r=0;r<t.length;++r)t[r].data.hook.insert(t[r])}var m=s("attrs,class,staticClass,staticStyle,key");function E(e,t,n,r){var o,i=t.tag,a=t.data,s=t.children;if(r=r||a&&a.pre,t.elm=e,j(t.isComment)&&A(t.asyncFactory))return t.isAsyncPlaceholder=!0;if(A(a)&&(A(o=a.hook)&&A(o=o.init)&&o(t,!0),A(o=t.componentInstance)))return d(t,n),!0;if(A(i)){if(A(s))if(e.hasChildNodes())if(A(o=a)&&A(o=o.domProps)&&A(o=o.innerHTML)){if(o!==e.innerHTML)return!1}else{for(var c=!0,l=e.firstChild,u=0;u<s.length;u++){if(!l||!E(l,s[u],n,r)){c=!1;break}l=l.nextSibling}if(!c||l)return!1}else h(t,s,n);if(A(a)){var f=!1;for(var p in a)if(!m(p)){f=!0,v(t,n);break}!f&&a.class&&Xe(a.class)}}else e.data!==t.text&&(e.data=t.text);return!0}return function(e,t,n,r,o,i){if(!$(t)){var a,s=!1,c=[];if($(e))s=!0,b(t,c,o,i);else{var l=A(e.nodeType);if(!l&&Gn(e,t))C(e,t,c,r);else{if(l){if(1===e.nodeType&&e.hasAttribute(M)&&(e.removeAttribute(M),n=!0),j(n)&&E(e,t,c))return x(t,c,!0),e;a=e,e=new se(_.tagName(a).toLowerCase(),{},[],void 0,a)}var u=e.elm,f=_.parentNode(u);if(b(t,c,u._leaveCb?null:f,_.nextSibling(u)),A(t.parent))for(var p=t.parent,d=w(t);p;){for(var h=0;h<g.destroy.length;++h)g.destroy[h](p);if(p.elm=t.elm,d){for(var v=0;v<g.create.length;++v)g.create[v](Hn,p);var m=p.data.hook.insert;if(m.merged)for(var y=1;y<m.fns.length;y++)m.fns[y]()}else Un(p);p=p.parent}A(f)?S(0,[e],0,0):A(e.tag)&&k(e)}}return x(t,c,s),t.elm}A(e)&&k(e)}}({nodeOps:qn,modules:[or,cr,pr,vr,{create:gr,activate:gr,remove:function(n,e){var r=n.elm;r._enterCb&&(r._enterCb.cancelled=!0,r._enterCb());var t=mr(n.data.transition);if(!t)return e();if(r._leaveCb)return;var o=t.leaveClass,i=t.leaveToClass,a=t.leaveActiveClass,s=t.beforeLeave,c=t.leave,l=t.afterLeave,u=t.leaveCancelled,f=t.delayLeave,p=c&&1<(c._length||c.length),d=n.context.$options.style||{},h=d[o],v=d[i]||d[a],m=d["@TRANSITION"]&&d["@TRANSITION"][a]||{},y=r._leaveCb=D(function(){r.parentNode&&r.parentNode._pending&&(r.parentNode._pending[n.key]=null),y.cancelled?u&&u(r):(e(),l&&l(r)),r._leaveCb=null});f?f(g):g();function g(){var e=n.context.$requireWeexModule("animation");function t(){e.transition(r.ref,{styles:v,duration:m.duration||0,delay:m.delay||0,timingFunction:m.timingFunction||"linear"},p?R:y)}y.cancelled||(n.data.show||((r.parentNode._pending||(r.parentNode._pending={}))[n.key]=n),s&&s(r),h?e.transition(r.ref,{styles:h},t):t(),c&&c(r,y),v||p||y())}}}].concat(nr),LONG_LIST_THRESHOLD:10}),br=Object.getOwnPropertyNames(de);function wr(e,r){var o=e.$el;return o&&"function"==typeof o[r]?function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];return o[r].apply(o,t)}:(te("Can't find component method \""+r+'" on '+o.type),R)}function kr(n,r){Array.isArray(r)&&(!function(p,n){for(var e=function(e,t){var f=br[e];F(n,f,function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];var r=this.length,o=de[f];"function"==typeof o&&o.apply(this,t);var i=wr(p,"removeData"),a=wr(p,"insertRange"),s=wr(p,"setListData");switch(f){case"push":a(r,t);break;case"pop":i(r-1,1);break;case"shift":i(0,1);break;case"unshift":a(0,t);break;case"splice":var c=t[0],l=t[1],u=t.slice(2);0<l&&i(c,l),0<u.length&&a(c,u);break;case"sort":case"reverse":s(this.slice())}})},t=0,r=br.length;t<r;t++)e(t)}(n,r),r.forEach(function(t,e){u(t)&&!f(t,"[[Watched]]")&&(F(t,"[[Watched]]",!0),n.$watch(function(){for(var e in t)t[e]},function(){wr(n,"updateData")(r.indexOf(t),t)},{deep:!0}))}))}var Sr={name:"recycle-list",methods:{closest:function(){for(var e,t=arguments,n=[],r=arguments.length;r--;)n[r]=t[r];return(e=this.$el).closest.apply(e,n)},queryElement:function(){for(var e,t=arguments,n=[],r=arguments.length;r--;)n[r]=t[r];return(e=this.$el).queryElement.apply(e,n)},queryElementAll:function(){for(var e,t=arguments,n=[],r=arguments.length;r--;)n[r]=t[r];return(e=this.$el).queryElementAll.apply(e,n)},scrollToElement:function(){for(var e,t=arguments,n=[],r=arguments.length;r--;)n[r]=t[r];return(e=this.$el).scrollToElement.apply(e,n)},resetLoadmore:function(){for(var e,t=arguments,n=[],r=arguments.length;r--;)n[r]=t[r];return(e=this.$el).resetLoadmore.apply(e,n)}},render:function(e){var t=this;if(this._vnode&&this.$options["[[UseCache]]"])return F(this.$options,"[[UseCache]]",!1),this._vnode;var n=this.$options.parent,r=this.$attrs.bindingExpression;return n&&r&&(n.$watch(r,function(){return F(t.$options,"[[UseCache]]",!0)},{deep:!0,immediate:!0}),kr(this,this.$attrs.listData),n.$watch(r,function(e){kr(t,e)})),this._events._attach_slot=function(e){nn(t.$parent||t,e.position,e.refs)},this._events._detach_slot=function(e){nn(t.$parent||t,e.position,e.refs,!0)},e("weex:recycle-list",{on:this._events},this.$slots.default)},renderError:function(e,t){return e("text",{style:{fontSize:"36px",color:"#FF0000"},value:t.toString()})}};function Or(e){if(e.length)return e.map(function(e){var t,n,r=(t=e).tag?t.tag.replace(/vue\-component\-(\d+\-)?/,""):"",o={type:r};if(r){if(o.style=function(e){if(e&&e.data){var t=e.data,n=t.staticStyle,r=t.staticClass;if(e.data.style||e.data.class||n||r){var o=Object.assign({},n,e.data.style),i=e.context.$options.style||{};return[].concat(r,e.data.class).forEach(function(e){e&&i[e]&&Object.assign(o,i[e])}),o}}}(e),e.data&&(o.attr=e.data.attrs,e.data.on&&(o.events=e.data.on)),"span"===r&&((n=e).children&&1===n.children.length&&!n.children[0].tag))return o.attr=o.attr||{},o.attr.value=e.children[0].text.trim(),o}else o.type="span",o.attr={value:(e.text||"").trim()};return e.children&&e.children.length&&(o.children=Or(e.children)),o})}var Cr={name:"richtext",render:function(e){return e("weex:richtext",{on:this._events,attrs:{value:Or(this.$options._renderChildren||[])}})}},xr={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function Er(e){var t=e&&e.componentOptions;return t&&t.Ctor.options.abstract?Er(it(t.children)):e}function $r(e){var t={},n=e.$options;for(var r in n.propsData)t[r]=e[r];var o=n._parentListeners;for(var i in o)t[h(i)]=o[i];return t}function Ar(e,t){if(/\d-keep-alive$/.test(t.tag))return e("keep-alive",{props:t.componentOptions.propsData})}var jr={name:"transition",props:xr,abstract:!0,render:function(e){var t=this,n=this.$slots.default;if(n&&(n=n.filter(function(e){return e.tag||ot(e)})).length){var r=this.mode,o=n[0];if(function(e){for(;e=e.parent;)if(e.data.transition)return!0}(this.$vnode))return o;var i=Er(o);if(!i)return o;if(this._leaving)return Ar(e,o);var a="__transition-"+this._uid+"-";i.key=null==i.key?i.isComment?a+"comment":a+i.tag:I(i.key)?0===String(i.key).indexOf(a)?i.key:a+i.key:i.key;var s,c,l=(i.data||(i.data={})).transition=$r(this),u=this._vnode,f=Er(u);if(i.data.directives&&i.data.directives.some(function(e){return"show"===e.name})&&(i.data.show=!0),f&&f.data&&(s=i,(c=f).key!==s.key||c.tag!==s.tag)&&!ot(f)&&(!f.componentInstance||!f.componentInstance._vnode.isComment)){var p=f.data.transition=N({},l);if("out-in"===r)return this._leaving=!0,Qe(p,"afterLeave",function(){t._leaving=!1,t.$forceUpdate()}),Ar(e,o);if("in-out"===r){if(ot(i))return u;var d,h=function(){d()};Qe(l,"afterEnter",h),Qe(l,"enterCancelled",h),Qe(p,"delayLeave",function(e){d=e})}}return o}}},Ir=N({tag:String,moveClass:String},xr);delete Ir.mode;var Mr={RecycleList:Sr,Richtext:Cr,Transition:jr,TransitionGroup:{props:Ir,created:function(){var e=this.$requireWeexModule("dom");this.getPosition=function(r){return new Promise(function(t,n){e.getComponentRect(r.ref,function(e){e.result?t(e.size):n(new Error("failed to get rect for element: "+r.tag))})})};var r=this.$requireWeexModule("animation");this.animate=function(t,n){return new Promise(function(e){r.transition(t.ref,n,e)})}},render:function(e){for(var t=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=$r(this),s=0;s<o.length;s++){var c=o[s];c.tag&&null!=c.key&&0!==String(c.key).indexOf("__vlist")&&(i.push(c),((n[c.key]=c).data||(c.data={})).transition=a)}if(r){var l=[],u=[];r.forEach(function(e){e.data.transition=a,n[e.key]?l.push(e):u.push(e)}),this.kept=e(t,null,l),this.removed=u}return e(t,null,i)},beforeUpdate:function(){this.__patch__(this._vnode,this.kept,!1,!0),this._vnode=this.kept},updated:function(){var e=this.prevChildren,t=this.moveClass||(this.name||"v")+"-move";e.length&&this.getMoveData(e[0].context,t)},methods:{getMoveData:function(e,t){var n=e.$options.style||{};return n["@TRANSITION"]&&n["@TRANSITION"][t]}}}},Tr=s("template,script,style,element,content,slot,link,meta,svg,view,a,div,img,image,text,span,input,switch,textarea,spinner,select,slider,slider-neighbor,indicator,canvas,list,cell,header,loading,loading-indicator,refresh,scrollable,scroller,video,web,embed,tabbar,tabheader,datepicker,timepicker,marquee,countdown",!0),Fr=(s("web,spinner,switch,video,textarea,canvas,indicator,marquee,countdown",!0),s("richtext,transition,transition-group,recycle-list",!0));s("embed,img,image,input,link,meta",!0);function Pr(e){return!(!e.$options||!e.$options.el)}An.mixin({beforeCreate:function(){Pr(this)&&Ue()},destroyed:function(){Pr(this)&&(Je.length=0,Le=Ve=null,Be=We=!1)}}),An.config.mustUseProp=function(e,t,n){return!1},An.config.isReservedTag=Tr,An.config.isRuntimeComponent=Fr,An.config.isUnknownElement=function(e){return!1},An.options.directives={},An.options.components=Mr,An.prototype.__patch__=_r,An.prototype.$mount=function(e,t){return n=this,r=e&&(i=this.$document,(a=i.createComment("root")).hasAttribute=a.removeAttribute=function(){},i.documentElement.appendChild(a),a),o=t,n.$el=r,n.$options.render||(n.$options.render=le),yt(n,"beforeMount"),new xt(n,function(){n._update(n._render(),o)},R,null,!0),o=!1,null==n.$vnode&&(n._isMounted=!0,yt(n,"mounted")),n;var n,r,o,i,a},e.Vue=An}});e(mr);var yr=n(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var f={};t.createInstanceContext=function(e,t,n){void 0===n&&(n={});var r,o,i,a,s=t.weex,c=(f[e]={instanceId:e,config:s.config,document:s.document,data:n}).Vue=function(e,t){var n={};mr(n,t.document);var r=n.Vue,o=f[e],i=/^weex:/i,a=r.config.isReservedTag||function(){return!1},s=r.config.isRuntimeComponent||function(){return!1};return r.config.isReservedTag=function(e){return!s(e)&&t.supports("@component/"+e)||a(e)||i.test(e)},r.config.parsePlatformTagName=function(e){return e.replace(i,"")},r.prototype.$instanceId=e,r.prototype.$document=o.document,r.prototype.$requireWeexModule=t.requireModule,r.mixin({beforeCreate:function(){var e=this.$options;if(e.el){var t=e.data,n=("function"==typeof t?t():t)||{};e.data=Object.assign(n,o.data),o.app=this}},mounted:function(){if(this.$options.el&&t.document&&o.app===this)try{t.document.taskCenter.send("dom",{action:"createFinish"},[])}catch(e){}}}),r.prototype.$getConfig=function(){if(o.app instanceof r)return o.config},r}(e,s),l=(r=e,o=s.requireModule,i=f[r],a=o("timer"),{setTimeout:function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];return a.setTimeout(function(){t[0].apply(t,t.slice(2))},t[1]),i.document.taskCenter.callbackManager.lastCallbackId.toString()},setInterval:function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];return a.setInterval(function(){t[0].apply(t,t.slice(2))},t[1]),i.document.taskCenter.callbackManager.lastCallbackId.toString()},clearTimeout:function(e){a.clearTimeout(e)},clearInterval:function(e){a.clearInterval(e)}}),u=Object.assign({Vue:c},l);return Object.freeze(u),u},t.destroyInstance=function(e){var t=f[e];if(t&&t.app instanceof t.Vue){try{t.app.$destroy(),t.document.destroy()}catch(e){}delete t.document,delete t.app}delete f[e]},t.refreshInstance=function(e,t){var n=f[e];if(!(n&&n.app instanceof n.Vue))return new Error("refreshInstance: instance "+e+" not found!");if(n.Vue&&n.Vue.set)for(var r in t)n.Vue.set(n.app,r,t[r]);n.document.taskCenter.send("dom",{action:"refreshFinish"},[])}}),gr=e(yr),_r=yr.createInstanceContext,br=yr.destroyInstance,wr=yr.refreshInstance,kr=Object.freeze({default:gr,__moduleExports:yr,createInstanceContext:_r,destroyInstance:br,refreshInstance:wr});var Sr=Object.freeze({$:function(e){console.warn("[JS Framework] Vm#$ is deprecated, please use Vm#$vm instead");var t=this._ids[e];if(t)return t.vm},$el:function(e){var t=this._ids[e];if(t)return t.el},$vm:function(e){var t=this._ids[e];if(t)return t.vm},$renderThen:function(e){return this._app.differ.then(function(){e()})},$scrollTo:function(e,t){console.warn("[JS Framework] Vm#$scrollTo is deprecated, please use \"require('@weex-module/dom').scrollTo(el, options)\" instead");var n=this.$el(e);n&&this._app.requireModule("dom").scrollToElement(n.ref,{offset:t})},$transition:function(e,n,r){var o=this,i=this.$el(e);i&&n&&n.styles&&this._app.requireModule("animation").transition(i.ref,n,function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];o._setStyle(i,n.styles),r&&r.apply(void 0,e)})},$getConfig:function(e){var t=this._app.options;return"function"==typeof e&&(console.warn("[JS Framework] the callback of Vm#$getConfig(callback) is deprecated, this api now can directly RETURN config info."),e(t)),t},$sendHttp:function(e,t){console.warn("[JS Framework] Vm#$sendHttp is deprecated, please use \"require('@weex-module/stream').sendHttp(params, callback)\" instead"),this._app.requireModule("stream").sendHttp(e,t)},$openURL:function(e){console.warn("[JS Framework] Vm#$openURL is deprecated, please use \"require('@weex-module/event').openURL(url)\" instead"),this._app.requireModule("event").openURL(e)},$setTitle:function(e){console.warn("[JS Framework] Vm#$setTitle is deprecated, please use \"require('@weex-module/pageInfo').setTitle(title)\" instead"),this._app.requireModule("pageInfo").setTitle(e)},$call:function(e,t){for(var n=[],r=arguments.length-2;0<r--;)n[r]=arguments[r+2];console.warn("[JS Framework] Vm#$call is deprecated, please use \"require('@weex-module/moduleName')\" instead");var o=this._app.requireModule(e);o&&o[t]&&o[t].apply(o,n)}});function Or(e){for(var t=[],n=arguments.length-1;0<n--;)t[n]=arguments[n+1];if("function"==typeof Object.assign)Object.assign.apply(Object,[e].concat(t));else{var r=t.shift();for(var o in r)e[o]=r[o];t.length&&Or.apply(void 0,[e].concat(t))}return e}function Cr(e,t,n,r){Object.defineProperty(e,t,{value:n,enumerable:!!r,writable:!0,configurable:!0})}function xr(e,t){if(e.length){var n=e.indexOf(t);if(-1<n)return e.splice(n,1)}}var Er=Object.prototype.hasOwnProperty;function $r(e,t){return Er.call(e,t)}function Ar(n,r){return function(e){var t=arguments.length;return t?1<t?n.apply(r,arguments):n.call(r,e):n.call(r)}}function jr(e){return null!==e&&"object"==typeof e}var Ir=Object.prototype.toString,Mr="[object Object]";function Tr(e){return Ir.call(e)===Mr}function Fr(e){var t=(e+"").charCodeAt(0);return 36===t||95===t}var Pr,Nr="__proto__"in{};function Rr(){return"object"==typeof nativeSet?nativeSet.create():new Pr}function Dr(e){var t=Object.prototype.toString.call(e);return t.substring(8,t.length-1).toLowerCase()}"undefined"!=typeof Set&&Set.toString().match(/native code/)?Pr=Set:((Pr=function(){this.set=Object.create(null)}).prototype.has=function(e){return void 0!==this.set[e]},Pr.prototype.add=function(e){null==e||this.set[e]||(this.set[e]=1)},Pr.prototype.clear=function(){this.set=Object.create(null)});var Vr=/^@weex-component\//,Lr=/^@weex-module\//,Jr=/^\.{1,2}\//,Wr=/\.js$/,qr=function(e){return!!e.match(Vr)},Br=function(e){return!!e.match(Lr)},Ur=function(e){return!!e.match(Jr)},zr=function(e){return!qr(e)&&!Br(e)&&!Ur(e)};function Hr(e){return e.replace(Vr,"").replace(Lr,"")}function Xr(e){return e.replace(Wr,"")}var Gr=0;function Kr(){this.id=Gr++,this.subs=[]}Kr.target=null;var Zr=[];function Yr(){Kr.target=null,Zr=[]}Kr.prototype.addSub=function(e){this.subs.push(e)},Kr.prototype.removeSub=function(e){xr(this.subs,e)},Kr.prototype.depend=function(){Kr.target&&Kr.target.addDep(this)},Kr.prototype.notify=function(){for(var e=this.subs.slice(),t=0,n=e.length;t<n;t++)e[t].update()};var Qr=0;function eo(e,t,n,r){r&&Or(this,r);var o="function"==typeof t;(this.vm=e)._watchers.push(this),this.expression=t,this.cb=n,this.id=++Qr,this.active=!0,this.dirty=this.lazy,this.deps=[],this.newDeps=[],this.depIds=Rr(),this.newDepIds=Rr(),o&&(this.getter=t),this.value=this.lazy?void 0:this.get(),this.queued=this.shallow=!1}eo.prototype.get=function(){var e;e=this,Kr.target&&Zr.push(Kr.target),Kr.target=e;var t=this.getter.call(this.vm,this.vm);return this.deep&&function e(t,n){var r,o,i,a;n||(n=to).clear();i=Array.isArray(t);a=jr(t);if(i||a){if(t.__ob__){var s=t.__ob__.dep.id;if(n.has(s))return;n.add(s)}if(i)for(r=t.length;r--;)e(t[r],n);else if(a)for(o=Object.keys(t),r=o.length;r--;)e(t[o[r]],n)}}(t),Kr.target=Zr.pop(),this.cleanupDeps(),t},eo.prototype.addDep=function(e){var t=e.id;this.newDepIds.has(t)||(this.newDepIds.add(t),this.newDeps.push(e),this.depIds.has(t)||e.addSub(this))},eo.prototype.cleanupDeps=function(){for(var e=this.deps.length;e--;){var t=this.deps[e];this.newDepIds.has(t.id)||t.removeSub(this)}var n=this.depIds;this.depIds=this.newDepIds,this.newDepIds=n,this.newDepIds.clear(),n=this.deps,this.deps=this.newDeps,this.newDeps=n,this.newDeps.length=0},eo.prototype.update=function(e){this.lazy?this.dirty=!0:this.run()},eo.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||(jr(e)||this.deep)&&!this.shallow){var t=this.value;this.value=e,this.cb.call(this.vm,e,t)}this.queued=this.shallow=!1}},eo.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},eo.prototype.depend=function(){for(var e=this.deps.length;e--;)this.deps[e].depend()},eo.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||this.vm._vForRemoving||xr(this.vm._watchers,this);for(var e=this.deps.length;e--;)this.deps[e].removeSub(this);this.active=!1,this.vm=this.cb=this.value=null}};var to=Rr();var no=Array.prototype,ro=Object.create(no);["push","pop","shift","unshift","splice","sort","reverse"].forEach(function(a){var s=no[a];Cr(ro,a,function(){for(var e=arguments,t=arguments.length,n=new Array(t);t--;)n[t]=e[t];var r,o=s.apply(this,n),i=this.__ob__;switch(a){case"push":case"unshift":r=n;break;case"splice":r=n.slice(2)}return r&&i.observeArray(r),i.dep.notify(),o})}),Cr(no,"$set",function(e,t){return console.warn('[JS Framework] "Array.prototype.$set" is not a standard API, it will be removed in the next version.'),e>=this.length&&(this.length=e+1),this.splice(e,1,t)[0]}),Cr(no,"$remove",function(e){console.warn('[JS Framework] "Array.prototype.$remove" is not a standard API, it will be removed in the next version.'),this.length&&("number"!=typeof e&&(e=this.indexOf(e)),-1<e&&this.splice(e,1))});var oo=Object.getOwnPropertyNames(ro);function io(e){(this.value=e,this.dep=new Kr,Cr(e,"__ob__",this),Array.isArray(e))?((Nr?ao:so)(e,ro,oo),this.observeArray(e)):this.walk(e)}function ao(e,t){e.__proto__=t}function so(e,t,n){for(var r=0,o=n.length;r<o;r++){var i=n[r];Cr(e,i,t[i])}}function co(e,t){var n;if(jr(e))return $r(e,"__ob__")&&e.__ob__ instanceof io?n=e.__ob__:(Array.isArray(e)||Tr(e))&&Object.isExtensible(e)&&!e._isVue&&(n=new io(e)),n&&t&&n.addVm(t),n}io.prototype.walk=function(e){for(var t in e)this.convert(t,e[t])},io.prototype.observeArray=function(e){for(var t=0,n=e.length;t<n;t++)co(e[t])},io.prototype.convert=function(e,t){!function(o,e,i){var a=new Kr,t=Object.getOwnPropertyDescriptor(o,e);if(t&&!1===t.configurable)return;var s=t&&t.get,n=t&&t.set,c=co(i);Object.defineProperty(o,e,{enumerable:!0,configurable:!0,get:function(){var e=s?s.call(o):i;if(Kr.target&&(a.depend(),c&&c.dep.depend(),Array.isArray(e)))for(var t=void 0,n=0,r=e.length;n<r;n++)(t=e[n])&&t.__ob__&&t.__ob__.dep.depend();return e},set:function(e){var t=s?s.call(o):i;e!==t&&(n?n.call(o,e):i=e,c=co(e),a.notify())}})}(this.value,e,t)},io.prototype.addVm=function(e){(this.vms||(this.vms=[])).push(e)},io.prototype.removeVm=function(e){xr(this.vms,e)};var lo=["$index","$value","$event"];function uo(t,n){(-1<lo.indexOf(n)||!Fr(n))&&Object.defineProperty(t,n,{configurable:!0,enumerable:!0,get:function(){return t._data[n]},set:function(e){t._data[n]=e}})}function fo(e){var t=e._data;Tr(t)||(t={});for(var n=Object.keys(t),r=n.length;r--;)uo(e,n[r]);co(t,e)}function po(){}function ho(e){var t=e._computed;if(t)for(var n in t){var r=t[n],o={enumerable:!0,configurable:!0};o.set="function"==typeof r?(o.get=vo(r,e),po):(o.get=r.get?!1!==r.cache?vo(r.get,e):Ar(r.get,e):po,r.set?Ar(r.set,e):po),Object.defineProperty(e,n,o)}}function vo(e,t){var n=new eo(t,e,null,{lazy:!0});return function(){return n.dirty&&n.evaluate(),Kr.target&&n.depend(),n.value}}var mo={nativeComponentMap:{text:!0,image:!0,container:!0,slider:{type:"slider",append:"tree"},cell:{type:"cell",append:"tree"}}},yo=mo.nativeComponentMap,go={attr:"setAttr",style:"setStyle",event:"addEvent"};function _o(e,t,n){var r,o,i,a,s,c;ko(e,t,n.id,e),r=e,o=t,i=n.attr,Oo(r,o,"attr",i),function(e,t,n){if("function"!=typeof n&&!Array.isArray(n))return;if(Array.isArray(n)&&!n.length)return t.setClassStyle({});var r=e._options&&e._options.style||{};if("function"==typeof n){var o=xo(e,n,function(e){So(t,r,e)});So(t,r,o)}else So(t,r,n)}(e,t,n.classList),a=e,s=t,c=n.style,Oo(a,s,"style",c),function(e,t,n){if(!n)return;var r=Object.keys(n),o=r.length;for(;o--;){var i=r[o],a=n[i];"string"==typeof a&&((a=e[a])||console.warn('[JS Framework] The event handler "'+a+'" is not defined.')),s=e,c=i,l=a,t.addEvent(c,Ar(l,s))}var s,c,l}(e,t,n.events)}function bo(e,t,n,r){void 0===r&&(r={}),function(e,t,n){var r=t._options&&t._options.style||{};if(!n._rootEl)return;var o="@originalRootEl";function i(e,t){"array"===Dr(e)&&e.unshift(t)}if(r[o]=n._rootEl.classStyle,"function"==typeof e){var a=xo(t,e,function(e){i(e,o),So(n._rootEl,r,e)});i(a,o),So(n._rootEl,r,a)}else null!=e&&(i(e,o),So(n._rootEl,r,e))}(n.classList,e,t),function(r,o,i){var e=function(t){var e=r[t];if("function"==typeof e){var n=xo(o,e,function(e){i._rootEl&&i._rootEl.setStyle(t,e)});i._rootEl.setStyle(t,n)}else i._rootEl&&i._rootEl.setStyle(t,e)};for(var t in r)e(t)}(n.style,e,t),r.children?r.children[r.children.length-1]._vm=t:r._vm=t}function wo(r,o,i,a){if(r){var e=function(t){if(!o||o[t]){var e=r[t];if("function"==typeof e){var n=xo(i,e,function(e){a[t]=e});a[t]=n}else a[t]=e}};for(var t in r)e(t)}}function ko(t,e,n,r){var o=Object.create(null);if(Object.defineProperties(o,{vm:{value:r,writable:!1,configurable:!1},el:{get:function(){return e||r._rootEl},configurable:!1}}),"function"==typeof n){var i=n;((n=i.call(t))||0===n)&&(t._ids[n]=o),xo(t,i,function(e){e&&(t._ids[e]=o)})}else n&&"string"==typeof n&&(t._ids[n]=o)}function So(e,n,r){"string"==typeof r&&(r=r.split(/\s+/)),r.forEach(function(e,t){r.splice.apply(r,[t,1].concat(e.split(/\s+/)))});for(var o={},t=r.length,i=function(e){var t=n[r[e]];t&&Object.keys(t).forEach(function(e){o[e]=t[e]})},a=0;a<t;a++)i(a);e.setClassStyle(o)}function Oo(e,t,n,r){if(r)for(var o=Object.keys(r),i=o.length;i--;){var a=o[i],s=r[a];"function"==typeof s?Co(e,t,n,a,s):t[go[n]](a,s)}}function Co(r,o,e,i,t){var a=go[e],n=xo(r,t,function(e){function t(){o[a](i,e)}var n=r&&r._app&&r._app.differ;n?n.append("element",o.depth||0,o.ref,t):t()});o[a](i,n)}function xo(e,t,n){return e._static?t.call(e,e):new eo(e,t,function(e,t){"object"!=typeof e&&e===t||n(e)}).value}function Eo(e,t){var n=e._app.doc.createComment("start"),r=e._app.doc.createComment("end"),o=$o++;if(t.element){var i=t.updateMark;i?(i.element&&(i=i.end),t.element.insertAfter(r,i),t.element.insertAfter(n,i),t.updateMark=r):(t.element.insertBefore(n,t.end),t.element.insertBefore(r,t.end)),t=t.element}else t.appendChild(n),t.appendChild(r);return{start:n,end:r,element:t,blockId:o}}var $o=1;function Ao(e,t,n){if(n.element){var r=n.end,o=n.updateMark;if(n.children&&n.children.push(t),o){var i=jo(e,t,o);return n.updateMark=t.element?t.end:t,i}if(!t.element)return n.element.insertBefore(t,r);n.element.insertBefore(t.start,r),n.element.insertBefore(t.end,r)}else{if(!t.element)return n.appendChild(t);n.appendChild(t.start),n.appendChild(t.end)}}function jo(e,t,n){return t.element?function(e,t){var n=t.parentNode;if(n){for(var r,o=e.start,i=[o];o&&o!==e.end;)o=o.nextSibling,i.push(o);var a=t;return i.every(function(e){return r=n.insertAfter(e,a),a=e,-1!==r}),r}}(t,n):function(e,t){var n=t.parentNode;if(n)return n.insertAfter(e,t)}(t,n)}function Io(e,t,n){void 0===n&&(n=!1),t.element?function(e,t){void 0===t&&(t=!1);var n=[],r=e.start.nextSibling;for(;r&&r!==e.end;)n.push(r),r=r.nextSibling;t||Mo(e.start);n.forEach(function(e){Mo(e)}),t||Mo(e.end)}(t,n):Mo(t),t._vm&&t._vm.$emit("hook:destroyed")}function Mo(e){var t=e.parentNode;t&&t.removeChild(e)}function To(e,t,n,r){if(-1!==(e._app||{}).lastSignal){if(t.attr&&t.attr.hasOwnProperty("static")&&(e._static=!0),c=t,Array.isArray(c))return i=t,a=r,s=Eo(o=e,n),void i.forEach(function(e){To(o,e,s,a)});var o,i,a,s,c,l,u,f;if(r=r||{},"content"===(l=t).type||"slot"===l.type)return console.debug('[JS Framework] compile "content" block by',t),void(e._content=Eo(e,n));if(u=t,!r.hasOwnProperty("repeat")&&u.repeat)return console.debug('[JS Framework] compile "repeat" logic by',t),void("document"===n.type?console.warn("[JS Framework] The root element does't support `repeat` directive!"):function(e,t,n){var r=t.repeat,o="function"==typeof r,i=r.getter||r.expression||r;"function"!=typeof i&&(i=function(){return[]});var a=r.key||"$index",s=r.value||"$value",c=r.trackBy||t.trackBy||t.attr&&t.attr.trackBy,l=Eo(e,n);l.children=[],l.data=[],l.vms=[],function(c,i,l,e){var u=l.vms,f=l.children,t=e.getter,p=e.trackBy,d=e.oldStyle,h=e.key,v=e.value;function m(e,t,n){var r;d?jr(r=e)?(r[h]=t,r.hasOwnProperty("INDEX")||Object.defineProperty(r,"INDEX",{value:function(){console.warn('[JS Framework] "INDEX" in repeat is deprecated, please use "$index" instead')}})):(console.warn("[JS Framework] Each list item must be an object in old-style repeat, please use `repeat={{v in list}}` instead."),(r={})[h]=t,r[v]=e):((r={})[h]=t,r[v]=e);var o=function(e,t){var n=Object.create(e);n._data=t,fo(n),ho(n),(n._realParent=e)._static&&(n._static=e._static);return n}(n,r);u.push(o),To(o,i,l,{repeat:e})}var n=Po(c,l,t,"repeat",function(e){if(console.debug('[JS Framework] the "repeat" item has changed',e),l&&e){var r=f.slice(),o=u.slice(),t=l.data.slice(),i={},a={};e.forEach(function(e,t){var n=p?e[p]:d?e[h]:t;null!=n&&""!==n&&(i[n]=e)});var s=[];t.forEach(function(e,t){var n=p?e[p]:d?e[h]:t;i.hasOwnProperty(n)?(a[n]={item:e,index:t,key:n,target:r[t],vm:o[t]},s.push(e)):Io(0,r[t])}),f.length=0,u.length=0,l.data=e.slice(),l.updateMark=l.start,e.forEach(function(e,t){var n=p?e[p]:d?e[h]:t,r=a[n];r?(r.item===s[0]?s.shift():(s.$remove(r.item),jo(0,r.target,l.updateMark)),f.push(r.target),u.push(r.vm),d?r.vm=e:r.vm[v]=e,r.vm[h]=t,l.updateMark=r.target):m(e,t,c)}),delete l.updateMark}});l.data=n.slice(0),n.forEach(function(e,t){m(e,t,c)})}(e,t,l,{getter:i,key:a,value:s,trackBy:c,oldStyle:o})}(e,t,n));if(f=t,!r.hasOwnProperty("shown")&&f.shown)return console.debug('[JS Framework] compile "if" logic by',t),void("document"===n.type?console.warn("[JS Framework] The root element does't support `if` directive!"):function(e,t,n,r){var o={shown:!0},i=Eo(e,n);n.element&&n.children&&n.children.push(i);r.repeat&&(o.repeat=r.repeat);a=e,s=t,c=i,l=o,u=Po(a,c,s.shown,"shown",function(e){console.debug('[JS Framework] the "if" item was changed',e),c&&!!c.display!=!!e&&(c.display=!!e,e?To(a,s,c,l):Io(0,c,!0))}),c.display=!!u,u&&To(a,s,c,l);var a,s,c,l,u}(e,t,n,r));var p=r.type||t.type;if(d=r,"function"!=typeof p||d.hasOwnProperty("type")){var d,h,v,m,y,g,_,b,w=p,k=function(e,t,n){var r;e._app&&e._app.customComponentMap&&(r=e._app.customComponentMap[n]);e._options&&e._options.components&&(r=e._options.components[n]);t.component&&(r=r||{});return r}(e,t,w);if(k)return console.debug("[JS Framework] compile composed component by",t),v=k,m=t,y=n,g=w,_=r,b=new(h=e).constructor(g,v,h,y,void 0,{"hook:init":function(){h._static&&(this._static=h._static),ko(h,null,m.id,this),this._externalBinding={parent:h,template:m}},"hook:created":function(){!function(e,t,n,r){n=n||{};var o=((t=t||{})._options||{}).props;Array.isArray(o)&&(o=o.reduce(function(e,t){return e[t]=!0,e},{})),wo(r,o,e,t),wo(n.attr,o,e,t)}(h,this,m,_.repeat)},"hook:ready":function(){this._content&&Fo(h,m,this._content)}}),void bo(h,b,m,y);console.debug("[JS Framework] compile native component by",t),function(e,t,n,r){var o;(function(e){var t=e.type,n=yo[t];if("object"==typeof n)for(var r in n)if(null==e[r])e[r]=n[r];else if("object"===Dr(e[r])&&"object"===Dr(n[r]))for(var o in n[r])null==e[r][o]&&(e[r][o]=n[r][o])})(t),o="_documentElement"===n.ref?(console.debug("[JS Framework] compile to create body for "+r),a=r,e._app.doc.createBody(a)):(console.debug("[JS Framework] compile to create element for "+r),i=r,e._app.doc.createElement(i));var i;var a;if(!e._rootEl){e._rootEl=o;var s=e._externalBinding||{},c=s.template,l=s.parent;if(c&&c.events&&l&&o)for(var u in c.events){var f=l[c.events[u]];f&&o.addEvent(u,Ar(f,l))}}_o(e,o,t),t.attr&&t.attr.append&&(t.append=t.attr.append);t.append&&(o.attr=o.attr||{},o.attr.append=t.append);var p="tree"===t.append,d=e._app||{};-1===d.lastSignal||p||(console.debug("[JS Framework] compile to append single node for",o),d.lastSignal=Ao(e,o,n));-1!==d.lastSignal&&Fo(e,t,o);-1!==d.lastSignal&&p&&(console.debug("[JS Framework] compile to append whole tree for",o),d.lastSignal=Ao(e,o,n))}(e,t,n,w)}else!function(n,r,e,t,o){var i=Or({type:t.call(n)},o),a=Eo(n,e);e.element&&e.children&&e.children.push(a);xo(n,t,function(e){var t=Or({type:e},o);Io(0,a,!0),To(n,r,a,t)}),To(n,r,a,i)}(e,t,n,p,r)}}function Fo(t,e,n){var r=t._app||{},o=e.children;o&&o.length&&o.every(function(e){return To(t,e,n),-1!==r.lastSignal})}function Po(e,t,n,r,o){var i=e&&e._app&&e._app.differ,a={},s=(t.element.depth||0)+1;return xo(e,n,function(e){a.latestValue=e,i&&!a.recorded&&i.append(r,s,t.blockId,function(){var e=a.latestValue;o(e),a.recorded=!1,a.latestValue=void 0}),a.recorded=!0})}function No(e,t){if(t instanceof No)return t;this.timestamp=Date.now(),this.detail=t,this.type=e;var n=!1;this.stop=function(){n=!0},this.hasStopped=function(){return n}}function Ro(e,t){var n=this,r=this._vmEvents[e];if(r){var o=new No(e,t);r.forEach(function(e){e.call(n,o)})}}function Do(e,t){var n=new No(e,t);this.$emit(e,n),!n.hasStopped()&&this._parent&&this._parent.$dispatch&&this._parent.$dispatch(e,n)}function Vo(t,e){var n=new No(t,e);this.$emit(t,n),!n.hasStopped()&&this._childrenVms&&this._childrenVms.forEach(function(e){e.$broadcast(t,n)})}function Lo(e,t){if(e&&"function"==typeof t){var n=this._vmEvents,r=n[e]||[];r.push(t),n[e]=r,"hook:ready"===e&&this._ready&&this.$emit("hook:ready")}}function Jo(e,t){if(e){var n=this._vmEvents;if(t){var r=n[e];r&&r.$remove(t)}else delete n[e]}}var Wo,qo=["init","created","ready","destroyed"];function Bo(e,t,n,r,o,i){n=n||{},this._parent=n._realParent?n._realParent:n,this._app=n._app||{},n._childrenVms&&n._childrenVms.push(this),!t&&this._app.customComponentMap&&(t=this._app.customComponentMap[e]);var a,s,c,l,u=(t=t||{}).data||{};(this._options=t,this._methods=t.methods||{},this._computed=t.computed||{},this._css=t.style||{},this._ids={},this._vmEvents={},this._childrenVms=[],this._type=e,function(t,e){var n=t._options||{},r=n.events||{};for(var o in r)t.$on(o,r[o]);for(var i in e)t.$on(i,e[i]);qo.forEach(function(e){t.$on("hook:"+e,n[e])})}(this,i),console.debug('[JS Framework] "init" lifecycle in Vm('+this._type+")"),this.$emit("hook:init"),this._inited=!0,this._data="function"==typeof u?u():u,o&&Or(this._data,o),(a=this)._watchers=[],fo(a),ho(a),function(e){var t=e._methods;if(t)for(var n in t)e[n]=t[n]}(a),console.debug('[JS Framework] "created" lifecycle in Vm('+this._type+")"),this.$emit("hook:created"),this._created=!0,t.methods&&t.methods.ready&&(console.warn('"exports.methods.ready" is deprecated, please use "exports.created" instead'),t.methods.ready.call(this)),this._app.doc)&&(this._parentEl=r||this._app.doc.documentElement,c=(s=this)._options||{},l=c.template||{},c.replace?l.children&&1===l.children.length?To(s,l.children[0],s._parentEl):To(s,l.children,s._parentEl):To(s,l,s._parentEl),console.debug('[JS Framework] "ready" lifecycle in Vm('+s._type+")"),s.$emit("hook:ready"),s._ready=!0)}(Wo=Bo.prototype).$emit=Ro,Wo.$dispatch=Do,Wo.$broadcast=Vo,Wo.$on=Lo,Wo.$off=Jo,Bo.prototype.$watch=function(e,t){xo(this,e,t)},Bo.set=function e(t,n,r){if(Array.isArray(t))return t.splice(n,1,r);if($r(t,n))t[n]=r;else if(t._isVue)e(t._data,n,r);else{var o=t.__ob__;if(o){if(o.convert(n,r),o.dep.notify(),o.vms)for(var i=o.vms.length;i--;)uo(o.vms[i],n);return r}t[n]=r}},Bo.delete=function(e,t){if($r(e,t)){delete e[t];var n=e.__ob__;if(n){if(n.dep.notify(),n.vms)for(var r=n.vms.length;r--;)o=n.vms[r],Fr(i=t)||delete o[i]}else e._isVue&&delete e._data[t]}var o,i};var Uo={};function zo(n,r){var e=function(e){var t=Uo[e];t||(t={},Uo[e]=t),n[e].forEach(function(e){"string"==typeof e&&(e={name:e}),t[e.name]&&!r||(t[e.name]=e)})};for(var t in n)e(t)}function Ho(e,t){return e.customComponentMap[t]}function Xo(e,t,n){var r=e.customComponentMap;r[t]?console.error("[JS Framework] define a component("+t+") that already exists"):r[t]=n}var Go=n(function(e,r){var f;r=e.exports=H,"object"==typeof process&&process.env,f=function(){},r.SEMVER_SPEC_VERSION="2.0.0";var o=256,i=Number.MAX_SAFE_INTEGER||9007199254740991,l=r.re=[],t=r.src=[],n=0,a=n++;t[a]="0|[1-9]\\d*";var s=n++;t[s]="[0-9]+";var c=n++;t[c]="\\d*[a-zA-Z-][a-zA-Z0-9-]*";var u=n++;t[u]="("+t[a]+")\\.("+t[a]+")\\.("+t[a]+")";var p=n++;t[p]="("+t[s]+")\\.("+t[s]+")\\.("+t[s]+")";var d=n++;t[d]="(?:"+t[a]+"|"+t[c]+")";var h=n++;t[h]="(?:"+t[s]+"|"+t[c]+")";var v=n++;t[v]="(?:-("+t[d]+"(?:\\."+t[d]+")*))";var m=n++;t[m]="(?:-?("+t[h]+"(?:\\."+t[h]+")*))";var y=n++;t[y]="[0-9A-Za-z-]+";var g=n++;t[g]="(?:\\+("+t[y]+"(?:\\."+t[y]+")*))";var _=n++,b="v?"+t[u]+t[v]+"?"+t[g]+"?";t[_]="^"+b+"$";var w="[v=\\s]*"+t[p]+t[m]+"?"+t[g]+"?",k=n++;t[k]="^"+w+"$";var S=n++;t[S]="((?:<|>)?=?)";var O=n++;t[O]=t[s]+"|x|X|\\*";var C=n++;t[C]=t[a]+"|x|X|\\*";var x=n++;t[x]="[v=\\s]*("+t[C]+")(?:\\.("+t[C]+")(?:\\.("+t[C]+")(?:"+t[v]+")?"+t[g]+"?)?)?";var E=n++;t[E]="[v=\\s]*("+t[O]+")(?:\\.("+t[O]+")(?:\\.("+t[O]+")(?:"+t[m]+")?"+t[g]+"?)?)?";var $=n++;t[$]="^"+t[S]+"\\s*"+t[x]+"$";var A=n++;t[A]="^"+t[S]+"\\s*"+t[E]+"$";var j=n++;t[j]="(?:^|[^\\d])(\\d{1,16})(?:\\.(\\d{1,16}))?(?:\\.(\\d{1,16}))?(?:$|[^\\d])";var I=n++;t[I]="(?:~>?)";var M=n++;t[M]="(\\s*)"+t[I]+"\\s+",l[M]=new RegExp(t[M],"g");var T=n++;t[T]="^"+t[I]+t[x]+"$";var F=n++;t[F]="^"+t[I]+t[E]+"$";var P=n++;t[P]="(?:\\^)";var N=n++;t[N]="(\\s*)"+t[P]+"\\s+",l[N]=new RegExp(t[N],"g");var R=n++;t[R]="^"+t[P]+t[x]+"$";var D=n++;t[D]="^"+t[P]+t[E]+"$";var V=n++;t[V]="^"+t[S]+"\\s*("+w+")$|^$";var L=n++;t[L]="^"+t[S]+"\\s*("+b+")$|^$";var J=n++;t[J]="(\\s*)"+t[S]+"\\s*("+w+"|"+t[x]+")",l[J]=new RegExp(t[J],"g");var W=n++;t[W]="^\\s*("+t[x]+")\\s+-\\s+("+t[x]+")\\s*$";var q=n++;t[q]="^\\s*("+t[E]+")\\s+-\\s+("+t[E]+")\\s*$";var B=n++;t[B]="(<|>)?=?\\s*\\*";for(var U=0;U<35;U++)f(U,t[U]),l[U]||(l[U]=new RegExp(t[U]));function z(e,t){if(e instanceof H)return e;if("string"!=typeof e)return null;if(e.length>o)return null;if(!(t?l[k]:l[_]).test(e))return null;try{return new H(e,t)}catch(e){return null}}function H(e,t){if(e instanceof H){if(e.loose===t)return e;e=e.version}else if("string"!=typeof e)throw new TypeError("Invalid Version: "+e);if(e.length>o)throw new TypeError("version is longer than "+o+" characters");if(!(this instanceof H))return new H(e,t);f("SemVer",e,t),this.loose=t;var n=e.trim().match(t?l[k]:l[_]);if(!n)throw new TypeError("Invalid Version: "+e);if(this.raw=e,this.major=+n[1],this.minor=+n[2],this.patch=+n[3],this.major>i||this.major<0)throw new TypeError("Invalid major version");if(this.minor>i||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>i||this.patch<0)throw new TypeError("Invalid patch version");n[4]?this.prerelease=n[4].split(".").map(function(e){if(/^[0-9]+$/.test(e)){var t=+e;if(0<=t&&t<i)return t}return e}):this.prerelease=[],this.build=n[5]?n[5].split("."):[],this.format()}r.parse=z,r.valid=function(e,t){var n=z(e,t);return n?n.version:null},r.clean=function(e,t){var n=z(e.trim().replace(/^[=v]+/,""),t);return n?n.version:null},(r.SemVer=H).prototype.format=function(){return this.version=this.major+"."+this.minor+"."+this.patch,this.prerelease.length&&(this.version+="-"+this.prerelease.join(".")),this.version},H.prototype.toString=function(){return this.version},H.prototype.compare=function(e){return f("SemVer.compare",this.version,this.loose,e),e instanceof H||(e=new H(e,this.loose)),this.compareMain(e)||this.comparePre(e)},H.prototype.compareMain=function(e){return e instanceof H||(e=new H(e,this.loose)),G(this.major,e.major)||G(this.minor,e.minor)||G(this.patch,e.patch)},H.prototype.comparePre=function(e){if(e instanceof H||(e=new H(e,this.loose)),this.prerelease.length&&!e.prerelease.length)return-1;if(!this.prerelease.length&&e.prerelease.length)return 1;if(!this.prerelease.length&&!e.prerelease.length)return 0;var t=0;do{var n=this.prerelease[t],r=e.prerelease[t];if(f("prerelease compare",t,n,r),void 0===n&&void 0===r)return 0;if(void 0===r)return 1;if(void 0===n)return-1;if(n!==r)return G(n,r)}while(++t)},H.prototype.inc=function(e,t){switch(e){case"premajor":this.prerelease.length=0,this.patch=0,this.minor=0,this.major++,this.inc("pre",t);break;case"preminor":this.prerelease.length=0,this.patch=0,this.minor++,this.inc("pre",t);break;case"prepatch":this.prerelease.length=0,this.inc("patch",t),this.inc("pre",t);break;case"prerelease":0===this.prerelease.length&&this.inc("patch",t),this.inc("pre",t);break;case"major":0===this.minor&&0===this.patch&&0!==this.prerelease.length||this.major++,this.minor=0,this.patch=0,this.prerelease=[];break;case"minor":0===this.patch&&0!==this.prerelease.length||this.minor++,this.patch=0,this.prerelease=[];break;case"patch":0===this.prerelease.length&&this.patch++,this.prerelease=[];break;case"pre":if(0===this.prerelease.length)this.prerelease=[0];else{for(var n=this.prerelease.length;0<=--n;)"number"==typeof this.prerelease[n]&&(this.prerelease[n]++,n=-2);-1===n&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error("invalid increment argument: "+e)}return this.format(),this.raw=this.version,this},r.inc=function(e,t,n,r){"string"==typeof n&&(r=n,n=void 0);try{return new H(e,n).inc(t,r).version}catch(e){return null}},r.diff=function(e,t){{if(Q(e,t))return null;var n=z(e),r=z(t);if(n.prerelease.length||r.prerelease.length){for(var o in n)if(("major"===o||"minor"===o||"patch"===o)&&n[o]!==r[o])return"pre"+o;return"prerelease"}for(var o in n)if(("major"===o||"minor"===o||"patch"===o)&&n[o]!==r[o])return o}},r.compareIdentifiers=G;var X=/^[0-9]+$/;function G(e,t){var n=X.test(e),r=X.test(t);return n&&r&&(e=+e,t=+t),n&&!r?-1:r&&!n?1:e<t?-1:t<e?1:0}function K(e,t,n){return new H(e,n).compare(new H(t,n))}function Z(e,t,n){return 0<K(e,t,n)}function Y(e,t,n){return K(e,t,n)<0}function Q(e,t,n){return 0===K(e,t,n)}function ee(e,t,n){return 0!==K(e,t,n)}function te(e,t,n){return 0<=K(e,t,n)}function ne(e,t,n){return K(e,t,n)<=0}function re(e,t,n,r){var o;switch(t){case"===":"object"==typeof e&&(e=e.version),"object"==typeof n&&(n=n.version),o=e===n;break;case"!==":"object"==typeof e&&(e=e.version),"object"==typeof n&&(n=n.version),o=e!==n;break;case"":case"=":case"==":o=Q(e,n,r);break;case"!=":o=ee(e,n,r);break;case">":o=Z(e,n,r);break;case">=":o=te(e,n,r);break;case"<":o=Y(e,n,r);break;case"<=":o=ne(e,n,r);break;default:throw new TypeError("Invalid operator: "+t)}return o}function oe(e,t){if(e instanceof oe){if(e.loose===t)return e;e=e.value}if(!(this instanceof oe))return new oe(e,t);f("comparator",e,t),this.loose=t,this.parse(e),this.semver===ie?this.value="":this.value=this.operator+this.semver.version,f("comp",this)}r.rcompareIdentifiers=function(e,t){return G(t,e)},r.major=function(e,t){return new H(e,t).major},r.minor=function(e,t){return new H(e,t).minor},r.patch=function(e,t){return new H(e,t).patch},r.compare=K,r.compareLoose=function(e,t){return K(e,t,!0)},r.rcompare=function(e,t,n){return K(t,e,n)},r.sort=function(e,n){return e.sort(function(e,t){return r.compare(e,t,n)})},r.rsort=function(e,n){return e.sort(function(e,t){return r.rcompare(e,t,n)})},r.gt=Z,r.lt=Y,r.eq=Q,r.neq=ee,r.gte=te,r.lte=ne,r.cmp=re,r.Comparator=oe;var ie={};function ae(e,t){if(e instanceof ae)return e.loose===t?e:new ae(e.raw,t);if(e instanceof oe)return new ae(e.value,t);if(!(this instanceof ae))return new ae(e,t);if(this.loose=t,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map(function(e){return this.parseRange(e.trim())},this).filter(function(e){return e.length}),!this.set.length)throw new TypeError("Invalid SemVer Range: "+e);this.format()}function se(e){return!e||"x"===e.toLowerCase()||"*"===e}function ce(e,t,n,r,o,i,a,s,c,l,u,f,p){return((t=se(n)?"":se(r)?">="+n+".0.0":se(o)?">="+n+"."+r+".0":">="+t)+" "+(s=se(c)?"":se(l)?"<"+(+c+1)+".0.0":se(u)?"<"+c+"."+(+l+1)+".0":f?"<="+c+"."+l+"."+u+"-"+f:"<="+s)).trim()}function le(e,t){for(var n=0;n<e.length;n++)if(!e[n].test(t))return!1;if(t.prerelease.length){for(n=0;n<e.length;n++)if(f(e[n].semver),e[n].semver!==ie&&0<e[n].semver.prerelease.length){var r=e[n].semver;if(r.major===t.major&&r.minor===t.minor&&r.patch===t.patch)return!0}return!1}return!0}function ue(e,t,n){try{t=new ae(t,n)}catch(e){return!1}return t.test(e)}function fe(e,t,n,r){var o,i,a,s,c;switch(e=new H(e,r),t=new ae(t,r),n){case">":o=Z,i=ne,a=Y,s=">",c=">=";break;case"<":o=Y,i=te,a=Z,s="<",c="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(ue(e,t,r))return!1;for(var l=0;l<t.set.length;++l){var u=t.set[l],f=null,p=null;if(u.forEach(function(e){e.semver===ie&&(e=new oe(">=0.0.0")),f=f||e,p=p||e,o(e.semver,f.semver,r)?f=e:a(e.semver,p.semver,r)&&(p=e)}),f.operator===s||f.operator===c)return!1;if((!p.operator||p.operator===s)&&i(e,p.semver))return!1;if(p.operator===c&&a(e,p.semver))return!1}return!0}oe.prototype.parse=function(e){var t=this.loose?l[V]:l[L],n=e.match(t);if(!n)throw new TypeError("Invalid comparator: "+e);this.operator=n[1],"="===this.operator&&(this.operator=""),n[2]?this.semver=new H(n[2],this.loose):this.semver=ie},oe.prototype.toString=function(){return this.value},oe.prototype.test=function(e){return f("Comparator.test",e,this.loose),this.semver===ie||("string"==typeof e&&(e=new H(e,this.loose)),re(e,this.operator,this.semver,this.loose))},oe.prototype.intersects=function(e,t){if(!(e instanceof oe))throw new TypeError("a Comparator is required");var n;if(""===this.operator)return n=new ae(e.value,t),ue(this.value,n,t);if(""===e.operator)return n=new ae(this.value,t),ue(e.semver,n,t);var r=!(">="!==this.operator&&">"!==this.operator||">="!==e.operator&&">"!==e.operator),o=!("<="!==this.operator&&"<"!==this.operator||"<="!==e.operator&&"<"!==e.operator),i=this.semver.version===e.semver.version,a=!(">="!==this.operator&&"<="!==this.operator||">="!==e.operator&&"<="!==e.operator),s=re(this.semver,"<",e.semver,t)&&(">="===this.operator||">"===this.operator)&&("<="===e.operator||"<"===e.operator),c=re(this.semver,">",e.semver,t)&&("<="===this.operator||"<"===this.operator)&&(">="===e.operator||">"===e.operator);return r||o||i&&a||s||c},(r.Range=ae).prototype.format=function(){return this.range=this.set.map(function(e){return e.join(" ").trim()}).join("||").trim(),this.range},ae.prototype.toString=function(){return this.range},ae.prototype.parseRange=function(e){var c=this.loose;e=e.trim(),f("range",e,c);var t=c?l[q]:l[W];e=e.replace(t,ce),f("hyphen replace",e),e=e.replace(l[J],"$1$2$3"),f("comparator trim",e,l[J]),e=(e=(e=e.replace(l[M],"$1~")).replace(l[N],"$1^")).split(/\s+/).join(" ");var n=c?l[V]:l[L],r=e.split(" ").map(function(e){return n=c,f("comp",t=e),a=n,t=t.trim().split(/\s+/).map(function(e){return function(a,e){f("caret",a,e);var t=e?l[D]:l[R];return a.replace(t,function(e,t,n,r,o){var i;return f("caret",a,e,t,n,r,o),i=se(t)?"":se(n)?">="+t+".0.0 <"+(+t+1)+".0.0":se(r)?"0"===t?">="+t+"."+n+".0 <"+t+"."+(+n+1)+".0":">="+t+"."+n+".0 <"+(+t+1)+".0.0":o?(f("replaceCaret pr",o),"-"!==o.charAt(0)&&(o="-"+o),"0"===t?"0"===n?">="+t+"."+n+"."+r+o+" <"+t+"."+n+"."+(+r+1):">="+t+"."+n+"."+r+o+" <"+t+"."+(+n+1)+".0":">="+t+"."+n+"."+r+o+" <"+(+t+1)+".0.0"):(f("no pr"),"0"===t?"0"===n?">="+t+"."+n+"."+r+" <"+t+"."+n+"."+(+r+1):">="+t+"."+n+"."+r+" <"+t+"."+(+n+1)+".0":">="+t+"."+n+"."+r+" <"+(+t+1)+".0.0"),f("caret return",i),i})}(e,a)}).join(" "),f("caret",t),s=n,t=t.trim().split(/\s+/).map(function(e){return a=e,t=s?l[F]:l[T],a.replace(t,function(e,t,n,r,o){var i;return f("tilde",a,e,t,n,r,o),i=se(t)?"":se(n)?">="+t+".0.0 <"+(+t+1)+".0.0":se(r)?">="+t+"."+n+".0 <"+t+"."+(+n+1)+".0":o?(f("replaceTilde pr",o),"-"!==o.charAt(0)&&(o="-"+o),">="+t+"."+n+"."+r+o+" <"+t+"."+(+n+1)+".0"):">="+t+"."+n+"."+r+" <"+t+"."+(+n+1)+".0",f("tilde return",i),i});var a,t}).join(" "),f("tildes",t),f("replaceXRanges",o=t,i=n),t=o.split(/\s+/).map(function(e){return function(u,e){u=u.trim();var t=e?l[A]:l[$];return u.replace(t,function(e,t,n,r,o,i){f("xRange",u,e,t,n,r,o,i);var a=se(n),s=a||se(r),c=s||se(o),l=c;return"="===t&&l&&(t=""),a?e=">"===t||"<"===t?"<0.0.0":"*":t&&l?(s&&(r=0),c&&(o=0),">"===t?(t=">=",s?(n=+n+1,o=r=0):c&&(r=+r+1,o=0)):"<="===t&&(t="<",s?n=+n+1:r=+r+1),e=t+n+"."+r+"."+o):s?e=">="+n+".0.0 <"+(+n+1)+".0.0":c&&(e=">="+n+"."+r+".0 <"+n+"."+(+r+1)+".0"),f("xRange return",e),e})}(e,i)}).join(" "),f("xrange",t),f("replaceStars",r=t,n),t=r.trim().replace(l[B],""),f("stars",t),t;var t,n,r,o,i,s,a}).join(" ").split(/\s+/);return this.loose&&(r=r.filter(function(e){return!!e.match(n)})),r=r.map(function(e){return new oe(e,c)})},ae.prototype.intersects=function(n,r){if(!(n instanceof ae))throw new TypeError("a Range is required");return this.set.some(function(e){return e.every(function(t){return n.set.some(function(e){return e.every(function(e){return t.intersects(e,r)})})})})},r.toComparators=function(e,t){return new ae(e,t).set.map(function(e){return e.map(function(e){return e.value}).join(" ").trim().split(" ")})},ae.prototype.test=function(e){if(!e)return!1;"string"==typeof e&&(e=new H(e,this.loose));for(var t=0;t<this.set.length;t++)if(le(this.set[t],e))return!0;return!1},r.satisfies=ue,r.maxSatisfying=function(e,t,n){var r=null,o=null;try{var i=new ae(t,n)}catch(e){return null}return e.forEach(function(e){i.test(e)&&(r&&-1!==o.compare(e)||(o=new H(r=e,n)))}),r},r.minSatisfying=function(e,t,n){var r=null,o=null;try{var i=new ae(t,n)}catch(e){return null}return e.forEach(function(e){i.test(e)&&(r&&1!==o.compare(e)||(o=new H(r=e,n)))}),r},r.validRange=function(e,t){try{return new ae(e,t).range||"*"}catch(e){return null}},r.ltr=function(e,t,n){return fe(e,t,"<",n)},r.gtr=function(e,t,n){return fe(e,t,">",n)},r.outside=fe,r.prerelease=function(e,t){var n=z(e,t);return n&&n.prerelease.length?n.prerelease:null},r.intersects=function(e,t,n){return e=new ae(e,n),t=new ae(t,n),e.intersects(t)},r.coerce=function(e){if(e instanceof H)return e;if("string"!=typeof e)return null;var t=e.match(l[j]);return null!=t?z((t[1]||"0")+"."+(t[2]||"0")+"."+(t[3]||"0")):null}});Go.SEMVER_SPEC_VERSION,Go.re,Go.src,Go.parse,Go.valid,Go.clean,Go.SemVer,Go.inc,Go.diff,Go.compareIdentifiers,Go.rcompareIdentifiers,Go.major,Go.minor,Go.patch,Go.compare,Go.compareLoose,Go.rcompare,Go.sort,Go.rsort,Go.gt,Go.lt,Go.eq,Go.neq,Go.gte,Go.lte,Go.cmp,Go.Comparator,Go.Range,Go.toComparators,Go.satisfies,Go.maxSatisfying,Go.minSatisfying,Go.validRange,Go.ltr,Go.gtr,Go.outside,Go.prerelease,Go.intersects,Go.coerce;function Ko(e){if(Go.valid(e))return e;for(var t=(e="string"==typeof e?e:"").split("."),n=0,r=[];n<3;){var o="string"==typeof t[n]&&t[n]?t[n]:"0";r.push(o),n++}return r.join(".")}function Zo(e,t,n){var r={isDowngrade:!0,errorType:1,code:1e3},o=e.toLowerCase();return r.errorMessage="Downgrade["+e+"] :: deviceInfo "+t+" matched criteria "+n,0<=o.indexOf("osversion")?r.code=1001:0<=o.indexOf("appversion")?r.code=1002:0<=o.indexOf("weexversion")?r.code=1003:0<=o.indexOf("devicemodel")&&(r.code=1004),r}function Yo(e,t,n,r){var o;if(console.debug("[JS Framework] bootstrap for "+t),qr(t))o=Hr(t);else{if(!zr(t))return new Error("Wrong component name: "+t);if(!Ho(e,o=Xr(t)))return new Error("It's not a component: "+t)}if("string"==typeof(n=Tr(n)?n:{}).transformerVersion&&"string"==typeof global.transformerVersion&&!Go.satisfies(n.transformerVersion,global.transformerVersion))return new Error("JS Bundle version: "+n.transformerVersion+" not compatible with "+global.transformerVersion);var i=function(e,t){t=Tr(t=t||global.WXEnvironment)?t:{};var n={isDowngrade:!1};if("function"===Dr(e)){var r=e.call(this,t,{semver:Go,normalizeVersion:Ko});n=(r=!!r)?Zo("custom","","custom params"):n}else{var o=(e=Tr(e)?e:{})[(t.platform||"unknow").toLowerCase()]||{};for(var i in t){var a=i,s=a.toLowerCase(),c=t[i],l=0<=s.indexOf("version"),u=0<=s.indexOf("devicemodel"),f=o[i];if(f&&l){var p=Ko(f),d=Ko(t[i]);if(Go.satisfies(d,p)){n=Zo(a,c,f);break}}else if(u&&0<=("array"===Dr(f)?f:[f]).indexOf(c)){n=Zo(a,c,f);break}}}return n}(n.downgrade);if(i.isDowngrade)return e.callTasks([{module:"instanceWrap",method:"error",args:[i.errorType,i.code,i.errorMessage]}]),new Error("Downgrade["+i.code+"]: "+i.errorMessage);n.viewport&&function(e,t){if(void 0===t&&(t={}),e&&e.callTasks)e.callTasks([{module:"meta",method:"setViewport",args:[t]}])}(e,n.viewport),e.vm=new Bo(o,null,{_app:e},null,r)}var Qo=function(o,e){for(var t,n,r,i=[],a=arguments.length-2;0<a--;)i[a]=arguments[a+2];if(console.debug("[JS Framework] define a component "+e),"function"==typeof(r=1<i.length?i[1]:i[0])&&(n=r,r=null),n){var s={exports:{}};n(function(e){if(qr(e)){var t=Hr(e);return Ho(o,t)}if(Br(e)){var n=Hr(e);return o.requireModule(n)}if(Ur(e)||zr(e)){var r=Xr(e);return o.commonModules[r]}},s.exports,s),r=s.exports}if(qr(e)){var c=Hr(e);Xo(o,c,r)}else if(Br(e)){zo(((t={})[Hr(e)]=r,t))}else if(Ur(e)){var l=Xr(e);o.commonModules[l]=r}else if(zr(e)){var u=Xr(e);r.template||r.style||r.methods?Xo(o,u,r):o.commonModules[u]=r}};function ei(e){console.debug("[JS Framework] Destory an instance("+e.id+")"),e.vm&&function e(t){delete t._app;delete t._computed;delete t._css;delete t._data;delete t._ids;delete t._methods;delete t._options;delete t._parent;delete t._parentEl;delete t._rootEl;if(t._watchers){for(var n=t._watchers.length;n--;)t._watchers[n].teardown();delete t._watchers}if(t._childrenVms){for(var r=t._childrenVms.length;r--;)e(t._childrenVms[r]);delete t._childrenVms}console.debug('[JS Framework] "destroyed" lifecycle in Vm('+t._type+")");t.$emit("hook:destroyed");delete t._type;delete t._vmEvents}(e.vm),e.id="",e.options=null,e.blocks=null,e.vm=null,e.doc.taskCenter.destroyCallback(),e.doc.destroy(),e.doc=null,e.customComponentMap=null,e.commonModules=null}function ti(e){e.differ.flush()}function ni(r,e,o,t){var i;console.debug("[JS Framework] Intialize an instance with:\n",o);var n,a=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return Qo.apply(void 0,[r].concat(e))},s=function(e,t,n){i=Yo(r,e,t,n||o),ti(r),r.doc.listener.createFinish(),console.debug("[JS Framework] After intialized an instance("+r.id+")")},c=Bo,l=r.doc,u=function(e){return r.requireModule(Hr(e))},f={config:r.options,define:a,bootstrap:s,requireModule:u,document:l,Vm:c};Object.freeze(f),"function"==typeof e?n=e.toString().substr(12):e&&(n=e.toString()),n='(function(global){\n\n"use strict";\n\n '+n+" \n\n})(Object.create(this))";var p=global.WXEnvironment,d={};if(p&&"Web"!==p.platform){var h=r.requireModule("timer");Object.assign(d,{setTimeout:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return h.setTimeout(function(){e[0].apply(e,e.slice(2))},e[1]),r.doc.taskCenter.callbackManager.lastCallbackId.toString()},setInterval:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return h.setInterval(function(){e[0].apply(e,e.slice(2))},e[1]),r.doc.taskCenter.callbackManager.lastCallbackId.toString()},clearTimeout:function(e){h.clearTimeout(e)},clearInterval:function(e){h.clearInterval(e)}})}var v=Object.assign({define:a,require:function(t){return function(e){i=Yo(r,t,{},e)}},bootstrap:s,register:function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return function(e,t,n){console.warn("[JS Framework] Register is deprecated, please install lastest transformer."),Xo(e,t,n)}.apply(void 0,[r].concat(e))},render:function(e,t){i=Yo(r,e,{},t)},__weex_define__:a,__weex_bootstrap__:s,__weex_document__:l,__weex_require__:u,__weex_viewmodel__:c,weex:f},d,t);return function(e,t){if("function"!=typeof compileAndRunBundle)return!1;var n=void 0,r=!1,o="(function (",i=[],a=[];for(var s in e)i.push(s),a.push(e[s]);for(var c=0;c<i.length-1;++c)o+=i[c],o+=",";o+=i[i.length-1],o+=") {",o+=t,o+="} )";try{var l=e.weex||{},u=l.config||{};(n=compileAndRunBundle(o,u.bundleUrl,u.bundleDigest,u.codeCachePath))&&"function"==typeof n&&(n.apply(void 0,a),r=!0)}catch(e){console.error(e)}return r}(v,n)||function(e,t){var n=[],r=[];for(var o in e)n.push(o),r.push(e[o]);n.push(t),(new(Function.prototype.bind.apply(Function,[null].concat(n)))).apply(void 0,r)}(v,n),i}var ri=function(e){this.id=e,this.map=[],this.hooks=[]};function oi(e,t){var n=e[t];for(var r in n)n[r]()}function ii(e,t){this.id=e,this.options=t||{},this.vm=null,this.customComponentMap={},this.commonModules={},this.doc=new mo.Document(e,this.options.bundleUrl,null,mo.Listener),this.differ=new ri(e)}ri.prototype.isEmpty=function(){return 0===this.map.length},ri.prototype.append=function(e,t,n,r){var o=this;void 0===t&&(t=0),this.hasTimer||(this.hasTimer=!0,setTimeout(function(){o.hasTimer=!1,o.flush(!0)},0));var i=this.map;i[t]||(i[t]={});var a=i[t];a[e]||(a[e]={}),"element"===e?(a[e][n]||(a[e][n]=[]),a[e][n].push(r)):a[e][n]=r},ri.prototype.flush=function(e){var t=this.map.slice();this.map.length=0,t.forEach(function(e){oi(e,"repeat"),oi(e,"shown"),function(e,t){var n=e[t];for(var r in n){var o=n[r];o.forEach(function(e){e()})}}(e,"element")});var n=this.hooks.slice();this.hooks.length=0,n.forEach(function(e){e()}),this.isEmpty()||this.flush()},ri.prototype.then=function(e){this.hooks.push(e)},ii.prototype.requireModule=function(e){return function(r,o){var e=Uo[o],t={},n=function(n){Object.defineProperty(t,n,{configurable:!0,enumerable:!0,get:function(){return function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return r.callTasks({module:o,method:n,args:e})}},set:function(e){if("function"==typeof e)return r.callTasks({module:o,method:n,args:[e]})}})};for(var i in e)n(i);return t}(this,e)},ii.prototype.updateActions=function(){return ti(this)},ii.prototype.callTasks=function(e){return t=this,"array"!==Dr(n=e)&&(n=[n]),n.forEach(function(e){r=t.doc.taskCenter.send("module",{module:e.module,method:e.method},e.args)}),r;var t,n,r},Object.freeze(ii),Object.freeze(ii.prototype);var ai={};var si=mo.nativeComponentMap;function ci(e){"object"==typeof e&&function(e,t){var n=e.prototype;for(var r in t)n.hasOwnProperty(r)||(n[r]=t[r])}(Bo,e)}global.registerMethods=ci;var li={fireEvent:function(e){for(var t=[],n=arguments.length-1;0<n--;)t[n]=arguments[n+1];return function t(n,e,r,o,i){if(console.debug('[JS Framework] Fire a "'+r+'" event on an element('+e+") in instance("+n.id+")"),!Array.isArray(e)){var a=n.doc.getRef(e);if(a){var s=n.doc.fireEvent(a,r,o,i);return n.differ.flush(),n.doc.taskCenter.send("dom",{action:"updateFinish"},[]),s}return new Error('invalid element reference "'+e+'"')}e.some(function(e){return!1!==t(n,e,r,o)})}.apply(void 0,[ai[e]].concat(t))},callback:function(e){for(var t=[],n=arguments.length-1;0<n--;)t[n]=arguments[n+1];return function(e,t,n,r){console.debug("[JS Framework] Invoke a callback("+t+") with",n,"in instance("+e.id+")");var o=e.doc.taskCenter.callback(t,n,r);return ti(e),e.doc.taskCenter.send("dom",{action:"updateFinish"},[]),o}.apply(void 0,[ai[e]].concat(t))}};ci(Sr),Object.freeze(Bo);var ui=Object.freeze({registerComponents:function(e){Array.isArray(e)&&e.forEach(function(e){e&&("string"==typeof e?si[e]=!0:"object"==typeof e&&"string"==typeof e.type&&(si[e.type]=e))})},registerModules:function(e){"object"==typeof e&&zo(e)},registerMethods:ci,createInstance:function(e,t,n,r,o){var i=(o||{}).services;Yr();var a,s=ai[e];return n=n||{},(a=s?new Error('invalid instance id "'+e+'"'):(s=new ii(e,n),ni(ai[e]=s,t,r,i)))instanceof Error?a:s},init:function(e){mo.Document=e.Document,mo.Element=e.Element,mo.Comment=e.Comment,mo.sendTasks=e.sendTasks,mo.Listener=e.Listener},refreshInstance:function(e,t){var n=ai[e];return n?function(e,t){console.debug("[JS Framework] Refresh with",t,"in instance["+e.id+"]");var n=e.vm;return n&&t?("function"==typeof n.refreshData?n.refreshData(t):Or(n,t),e.differ.flush(),void e.doc.taskCenter.send("dom",{action:"refreshFinish"},[])):new Error('invalid data "'+t+'"')}(n,t):new Error('invalid instance id "'+e+'"')},destroyInstance:function(e){"function"==typeof markupState&&markupState(),Yr();var t=ai[e];if(!t)return new Error('invalid instance id "'+e+'"');ei(t),delete ai[e];var n=Math.round(e);return 0<n&&(n%18||"function"!=typeof notifyTrimMemory||notifyTrimMemory()),ai},receiveTasks:function(r,e){if(ai[r]&&Array.isArray(e)){var o=[];return e.forEach(function(e){var t=li[e.method],n=[].concat(e.args);"function"==typeof t&&(n.unshift(r),o.push(t.apply(void 0,n)))}),o}return new Error('invalid instance id "'+r+'" or tasks')},getRoot:function(e){var t,n=ai[e];return n?(t=(n.doc||{}).body||{}).toJSON?t.toJSON():{}:new Error('invalid instance id "'+e+'"')}}),fi={Vanilla:vr,Vue:kr,Rax:e(n(function(e){e.exports=function(n){var r={};function o(e){if(r[e])return r[e].exports;var t=r[e]={i:e,l:!1,exports:{}};return n[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}return o.m=n,o.c=r,o.d=function(e,t,n){o.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:n})},o.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=0)}([function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.getInstance=r,t.init=function(e){c=e.Document,e.Element,e.Comment},t.createInstanceContext=function(e,t,n){var r=l[e],o=t.weex;{if(null!=r)throw new Error('Instance id "'+e+'" existed when create instance');var i=o.config.bundleUrl;i?i.split("//")[0]||(i="https:"+i):(console.error('Error: Must have bundleUrl option when createInstance, downgrade to "about:blank".'),i="about:blank");var a=new c(e,i);r=l[e]={document:a,instanceId:e,bundleUrl:i,__weex_data__:n,uid:0};var s={instanceId:e,bundleUrl:i,document:a,__weex_document__:a,__weex_options__:t,__weex_data__:n||{},callNative:function(){},__weex_config__:t};return s}},t.refreshInstance=function(e,t){var n=r(e).document;n.documentElement.fireEvent("refresh",{timestamp:Date.now(),data:t}),n.taskCenter.send("dom",{action:"refreshFinish"},[])},t.destroyInstance=function(e){var t=r(e),n=(t.bundleCode,t.document);n.documentElement.fireEvent("destory",{timestamp:Date.now()}),n.destroy&&n.destroy();n.taskCenter&&n.taskCenter.destroyCallback&&n.taskCenter.destroyCallback();delete l[e]};var c=void 0,l={};function r(e){var t=l[e];if(!t)throw new Error('Invalid instance id "'+e+'"');return t}t.default=t}])})),Weex:ui};var pi,di,hi,vi,mi=Object.freeze({$userTrack:function(e,t,n,r){console.error("[Upgrade Warning] $userTrack will be removed in the next version!"),console.error("[JS Framework] Vm#$userTrack is deprecated, please use \"require('@weex-module/userTrack').commit(type, name, comName, param)\" instead"),this._app.requireModule("userTrack").commit(e,t,n,r)},$sendMtop:function(e,t){console.error("[Upgrade Warning] $sendMtop will be removed in the next version!"),console.error("[JS Framework] Vm#$sendMtop is deprecated, please use \"require('@weex-module/stream').sendMtop(params, callback)\" instead"),"undefined"==typeof window?this._app.requireModule("windvane").call({class:"MtopWVPlugin",method:"send",data:e},t):this._app.requireModule("stream").sendMtop(e,t)},$callWindvane:function(e,t){console.error("[Upgrade Warning] $callWindvane will be removed in the next version!"),console.error("[JS Framework] Vm#$callWindvane is deprecated, please use \"require('@weex-module/windvane').call(params, callback)\" instead"),this._app.requireModule("windvane").call(e,t)},$setSpm:function(e,t){console.error("[Upgrade Warning] $setSpm will be removed in the next version!"),console.error("[JS Framework] Vm#$setSpm is deprecated, please use \"require('@weex-module/pageInfo').setSpm(a, b)\" instead"),this._app.requireModule("pageInfo").setSpm(e,t)},$getUserInfo:function(e){console.error("[Upgrade Warning] $getUserInfo will be removed in the next version!"),console.error("[JS Framework] Vm#$getUserInfo is deprecated, please use \"require('@weex-module/user').getUserInfo(callback)\" instead"),this._app.requireModule("user").getUserInfo(e)},$login:function(e){console.error("[Upgrade Warning] $login will be removed in the next version!"),console.error("[JS Framework] Vm#$login is deprecated, please use \"require('@weex-module/user').login(callback)\" instead"),this._app.requireModule("user").login(e)},$logout:function(e){console.error("[Upgrade Warning] $logout will be removed in the next version!"),console.error("[JS Framework] Vm#$logout is deprecated, please use \"require('@weex-module/user').logout(callback)\" instead"),this._app.requireModule("user").logout(e)}}),yi=n(function(e,t){console.log("Start windmill weex-vue-plugin (0.3.2) framework. Build at 2018-09-18 13:06"),e.exports=function(){"function"!=typeof Object.assign&&Object.defineProperty(Object,"assign",{writable:!0,enumerable:!1,configurable:!0,value:function(e,t){var n=arguments;if(null==e)throw new TypeError("Cannot convert undefined or null to object");for(var r=Object(e),o=1;o<arguments.length;o++){var i=n[o];if(null!=i)for(var a in i)Object.prototype.hasOwnProperty.call(i,a)&&(r[a]=i[a])}return r}});var t,i=(t=1e5,function(){var e=String(t);return t+=1,e});function s(t,n,e){void 0===e&&(e=!0);var r=void 0!==global?global:"undefined"!=typeof self?self:new Function("return this")();try{Object.defineProperty(r,t,{value:n,configurable:!0,enumerable:!0,writable:!e})}catch(e){r[t]=n}}function c(e){return Object.prototype.toString.call(e).slice(8,-1)}function l(e){return"Object"===c(e)}function o(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n]}function f(o,i){var a;return void 0===i&&(i=0),"function"!=typeof setTimeout||"function"!=typeof clearTimeout?(console.warn("[Warn] There is no timer API in the current context."),o):function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];var r=this;clearTimeout(a),a=setTimeout(function(){return o.apply(r,t)},i)}}var n=function(){},u={},a=["Android","iOS"];function r(e,t){return"object"==typeof process&&process&&process.env&&"test"===process.env.PURPOSE?"function"==typeof __test_logger__&&(n=__test_logger__,!0):(u.debugMode,!0)}function p(e,t){r()&&n("log",e)}function d(e,t){r()&&n("debug",e)}function h(e,t){r()&&n("warn",e)}function v(e,t){r()&&n("error",e)}function m(e){if(v(e),"test"!==process.env.PURPOSE)throw new Error(e)}n=function(e,t){var n,r="["+((n=e).charAt(0).toUpperCase()+n.slice(1))+"][wml-r] "+t;return u.isWeex&&-1<a.indexOf(u.platform)?console.log(r):console.error(r)};var y={network:["request","uploadFile"],miniApp:["setAppShareInfo","hideLauncherLoading","setWebViewTop","setWebViewBackgroundImage"],mtop:["request"],storage:["length","setItem","getItem","removeItem"],memoryStorage:["setItem","getItem"],tabBar:["show","hide"],navigator:["push","pop","openMessagePage","reloadPage","getBackStack","popToHome","navigateTo","redirectTo","switchTab"],user:["login","logout","info"],modal:["alert","confirm","toast","showLoading","hideLoading"],navigatorBar:["show","hide","setTitle","setRightItem","setStyle","setDrawer","setActionSheet","hasIndexBadge","scaleIndexBadge","resetIndexBadge","getHeight","openDrawer","isDrawerOpened","closeDrawer","setLeftItem","showMenu","hideMenu","getStatusBarHeight","setNavigationBar"],clipboard:["writeText","readText"],picker:["pick","pickDate","pickTime","chooseCity"],webSocket:["webSocket","send","close","onOpen","onMessage","onClose","onError"],calendar:["addEvent","checkEvent","removeEvent"],connection:["getType","getDownlinkMax","onChange"],screen:["setAlwaysOn","setBrightness","getScreenBrightness"],broadcast:["createChannel","postMessage","onMessage","close"],share:["doShare"],cookie:["read","write","getAllObjects"],audio:["load","play","pause","stop","setVolume","canPlayType"],wopc:["authLogin","checkAuthSession","doAuth","getSessionKey","setSessionKey"],WopcMtopPlugin:["request"],device:["onShake","vibrate"],keyboard:["hideKeyboard"],contact:["choosePhoneContact"],location:["getLocation"],alipay:["tradePay"],userTrack:["commit","commitut","commitEvent","customAdvance","pageAppear","pageDisappear","skipPage","updatePageUtparam","updateNextPageUtparam"],"nuvajs-exec":["exec"],aluWVJSBridge:["userIsLogin","refreshAlipayCookie"],TBDeviceInfo:["getUtdid"],actionSheet:["showActionSheet"],image:["chooseImage","previewImage","compressImage","getImageInfo","saveImage"],media:["startVoice","stopVoice"],audioRecord:["startRecord","stopRecord","cancelRecord"],audioPlayer:["playVoice","pauseVoice","stopVoice"],file:["saveFile","getFileInfo","getFileList","removeFile"],video:["chooseVideo","getVideoInfo"],phone:["makePhoneCall"],compass:["startCompass","stopCompass","onCompassChange"],tbsecurity:["secureToken"]};function g(o,e){var i=e||function(){for(var e,t=arguments,n=[],r=arguments.length;r--;)n[r]=t[r];return(e=o()).$call.apply(e,n)};return function(o){if(!o)return d("Require a universal module proxy."),{call:i};var e=y[o];if(Array.isArray(e)){d('Require the "'+o+'" module.');var t={};return e.forEach(function(r){t[r]=function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];return i.apply(void 0,[o+"."+r].concat(t))}}),t}h('Require unknown module "'+o+"\".It may not exist or haven't been registered.")}}var _="[[WorkerPageReady]]",b="[[RendererPageReady]]",w="[[SendInitialState]]",k="[[ReceivedInitialState]]",S="[[WorkerPageStateChange]]",O="[[RendererPageStateChange]]",C="__WINDMILL_MODULE_GETTER__",e=function(){};e.prototype.$on=function(e,t){return void 0===t&&(t=o),d('$on "'+e+'"'),!e&&m("invalid event name "+e+" for windmill.$on."),t===o&&m("bind event "+e+" with no callback through windmill.$on."),this.bridge.onReceiveMessage({data:{type:e},origin:this.label,type:"Event"},t)},e.prototype.$once=function(e,t){return void 0===t&&(t=o),d('$once "'+e+'"'),!e&&m("invalid event name "+e+" for windmill.$once."),t===o&&m("bind event "+e+" with no callback through windmill.$once."),this.bridge.onReceiveMessage({data:{type:e,once:!0},origin:this.label,type:"Event"},t)},e.prototype.$off=function(e,t){return d('$off "'+e+'"'),!e&&m("invalid event name "+e+" for windmill.$off."),this.bridge.unbindEventListener("Event."+e,t)},e.prototype.$cycle=function(e,t){return void 0===t&&(t=o),d('$cycle "'+e+'"'),e&&/^app:|^page(:|@)/.test(e)||m("invalid lifecycle name "+e+" for windmill.$cycle."),t===o&&m("hook lifecycle "+e+" with no callback function through windmill.$cycle."),"AppWorker"!==this.label&&/^app:/.test(e)&&m("Shouldn't bind lifecycle hook for app in a page client."),this.bridge.onReceiveMessage({type:"Lifecycle",origin:this.label,data:{type:e}},t)},e.prototype.$decycle=function(e,t){return d('$decycle "'+e+'"'),e&&/^app:|^page(:|@)/.test(e)||m("invalid lifecycle name "+e+" for windmill.$decycle."),this.bridge.unbindEventListener("Lifecycle."+e,t)},e.prototype.$emit=function(e,t,n){return void 0===t&&(t={}),d('$emit("'+e+'")'),!e&&m("invalid event name "+e+" for windmill.$emit."),n&&n!==this.label?this.bridge.postMessage({data:{type:e,data:t},origin:this.label,target:n,type:"Event"}):this.bridge.emitEvent(""+e,t)},e.prototype.$callAsync=function(n,r){var o=this;return void 0===r&&(r={}),d('$callAsync "'+n+'"'),n||m("invalid method name "+n+" for windmill.$callAsync."),new Promise(function(e,t){o.bridge.dispatchMessage({type:"ModuleCall",origin:o.label,target:"AppWorker",data:{method:n,params:r}},e,t,!1)})},e.prototype.$call=function(e,t,n,r){return void 0===t&&(t={}),void 0===n&&(n=o),void 0===r&&(r=o),d('$call "'+e+'", params: '+JSON.stringify(t)),e||m("invalid method name "+e+" for windmill.$call."),this.bridge.dispatchMessage({type:"ModuleCall",origin:this.label,target:"AppWorker",data:{method:e,params:t}},n,r,!0)},e.prototype.$registerModules=function(e){!function(r,o){if(void 0===o&&(o=!1),!l(r))return v("Invalid parameter type! The module definition is not a plain object.");var e=function(t){var e=r[t];y[t]?o||h('The "'+t+'" module has already been registered.It would be overridden.'):y[t]=[];var n=y[t];Array.isArray(e)?e.forEach(function(e){-1===n.indexOf(e)?n.push(e):o||h('The "'+e+'" of the "'+t+'" module has already been registered.')}):v('Invalid parameter type! The method list of the "'+t+'" module should be an Array.')};for(var t in r)e(t)}(e,!0)},e.prototype.$getAvailableModules=function(){return function(e){var t={};try{t=JSON.parse(JSON.stringify(e))}catch(e){}return t}(y)};var x="[[EVENT_MAP]]";function E(e,t){var n=e[x];return Array.isArray(n[t])||(n[t]=[]),n[t]}var $,A=function(){d("Create new EventEmitter."),Object.defineProperty(this,x,{configurable:!1,enumerable:!1,writable:!1,value:{}})};function j(t){var n;try{n=JSON.stringify(t)}catch(e){n=t}m("failed to postMessage: "+n)}function I(e,t,n,r,o,i){var a=t+"."+n;return e.WindVane?e.WindVane.call(t,n,r,o,i):m("should have WindVane in global context"+(a?" to call "+a:"")+".")}A.prototype.on=function(e,t){d('EventEmitter: on("'+e+'")');var n=E(this,e);return n.push({listener:t,once:!1,callCount:0}),this},A.prototype.once=function(e,t){d('EventEmitter: once("'+e+'")');var n=E(this,e);return n.push({listener:t,once:!0,callCount:0}),this},A.prototype.off=function(e,t){d('EventEmitter: off("'+e+'"'+(t?", listener":"")+")");var n=this[x];if(t){var r=n[e];if(Array.isArray(r)){var o=r.findIndex(function(e){return e.listener===t});-1!==o&&r.splice(o,1)}}else delete n[e];return this};var M=!(A.prototype.emit=function(t){for(var e=arguments,n=[],r=arguments.length-1;0<r--;)n[r]=e[r+1];d('EventEmitter: emit("'+t+'", '+JSON.stringify(n)+")");var o=this[x],i=o[t];return Array.isArray(i)&&(o[t]=i.filter(function(e){try{e.listener.apply(null,n),e.callCount+=1}catch(e){return v('Failed to emit "'+t+'" event.'),v(e.toString()),!0}return!e.once})),this}),T=function(){this._messages=[]};T.prototype.postMessage=function(e){d("cache message in lazyMsgModule. "+JSON.stringify(e)),this._messages.push(e)},T.prototype.replaceWith=function(e){F=!1,this._messageModule=e,this._flush()},T.prototype._flush=function(){var t=this;this._messages.forEach(function(e){return t._messageModule.postMessage(e)})};var F,P,N=new T;function R(e,t){var n,r=e?(n=e).requireModule("@weex/windmill")||n.requireModule("windmill"):function(){if(!$){var t="undefined"!=typeof window?window:global;$={postMessage:function(e){return I(t,"Windmill","postMessage",e,function(){},j)},onmessage:function(e){if(console.debug("Set onMessage for webview."),!M)return M=!0,I(t,"Windmill","onMessage",{},e,j)}}}return $}();if(!r)return m("can't find message module ("+(e?"windmill module":"message module in webview")+")."),F=!0,N;if("function"==typeof t){d('Set the "onmessage" method to the bridge through callback.');try{r.onmessage(t)}catch(e){v('Failed to set the "onmessage" method to the bridge through callback.'),v(e.toString())}}return F&&N.replaceWith(r),r}function D(e){var t=e.match(/([^@]+)(@\S+)/);return t&&t[1]||e}var V=function(e,t){var a=this;void 0===t&&(t={}),d("Create a new RendererBridge."),P=t.isWeex,this._emitter=new A,d("Register onmessage api for "+(P?"Weex windmill module":"webview")+"."),P&&(this._weex=e),this._onMessage=function(e){if(d("Receive message from the worker. (message: "+JSON.stringify(e)+")"),!l(e)&&(v("The parameter of onmessage should be a plain object! Not "+c(e)),"string"==typeof e))try{e=JSON.parse(e)}catch(e){return void v("Failed to parse the message string. "+e.toString())}var t=e.type,n=e.data;void 0===n&&(n={});var r=e.origin,o=e.callbackId;switch(t){case"Callback":a._emitter.emit("callback@AppWorker:"+o,n);break;case"Event":var i=D(n.type);a._emitter.emit(t+"."+i,Object.assign({origin:r},n,{type:i}));break;case"Lifecycle":a._emitter.emit(t+"."+n.lifecycle,n.options);break;case"SetData":a._emitter.emit("Event.setdata",n);break;default:m('Unknown message type received from worker: "'+t+'"')}},R(e,this._onMessage)};V.prototype.dispatchMessage=function(t,n,r,e){d("Dispatch message to worker. (message: "+JSON.stringify(t)+")"),t.callbackId=this._genCallbackId(function(e){return e.status&&"SUCCESS"===e.status?n(e):(e.status,v("call API "+t.data.method+" from renderer failed: "+e.status+", "+e.error),r(e))},{keepAlive:e});try{t.keepAlive=!0,this.postMessage(t)}catch(e){r(e)}},V.prototype.postMessage=function(e){try{d("Call postMessage to worker. (message: "+JSON.stringify(e)+")"),R(this._weex,this._onMessage).postMessage(e)}catch(e){m(e.message||e.toString()||"postMessage failed.")}},V.prototype._genCallbackId=function(e,t){var n=t.keepAlive,r=t.callbackId,o=r||i();return this._emitter[n?"on":"once"]("callback@AppWorker:"+o,e),o},V.prototype.onReceiveMessage=function(e,t){var n=e.type,r=e.data;void 0===r&&(r={});var o=r.type;"Event"===n&&(o=D(o),r.type=o);var i=r.once?"once":"on";this._emitter[i](n+"."+o,t)},V.prototype.unbindEventListener=function(e,t){this._emitter.off(D(e),t)},V.prototype.emitEvent=function(e,t){void 0===t&&(t={});var n=D(e);this._emitter.emit("Event."+n,{type:n,data:t})};var L=function(n){function e(e,t){n.call(this),e&&l(e.config)&&(this._name=e.config.pageName||"",this.label=e.config.clientId||"",e.config.availableModules?(this.$registerModules(e.config.availableModules),this._gotAvailableModulesFromWeex=!0):h("No available modules in weex options.")),d("Create a new RendererRuntime. ("+this.label+", "+this._name+")"),this.bridge=new V(e,t),this._init()}return n&&(e.__proto__=n),((e.prototype=Object.create(n&&n.prototype)).constructor=e).prototype._init=function(){var t=this;this.bridge.onReceiveMessage({origin:"AppWorker",target:this.label,type:"Event",data:{type:"registerModules"}},function(e){e&&"registerModules"===e.type&&(d("Register available modules in renderer. ("+Object.keys(e.data)+")"),t.$registerModules(e.data))})},e.prototype.ready=function(){this.bridge.dispatchMessage({origin:this.label,target:"AppWorker",type:"Event",data:{type:"[[RendererRuntimeReady]]",data:{label:this.label,handshake:!this._gotAvailableModulesFromWeex}}},o,o)},e}(e),J=["$on","$once","$off","$emit","$cycle","$decycle","$call","$callAsync","$navTo","$getAvailableModules"];function W(e,t){var n=!(!e||!e.requireModule);!function(e){if(!e||!e.platform)return console.error("set logger environment failed.");Object.assign(u,e)}({platform:n&&e.config.env.platform,debugMode:n&&e.config.env.debugMode,isWeex:n}),d("Setup Windmill renderer framework."),e&&!e.requireModule&&(t=e,e=void 0),t||(t={}),d("Instantiate renderer in "+(((t=Object.assign({},t)).isWeex=n)?"Weex container":"WindVane container")+".");var o,i,r=new L(e,t),a=(o=r,i={},J.forEach(function(r){"function"==typeof o[r]&&(i[r]=function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];return o[r].apply(o,t)})}),i);return d("Prepare runtime APIs: "+JSON.stringify(J)),t.exposeModuleGetter&&s(C,g(function(){return a})),r.ready(),a}var q=/^@(windmill|weex)\/([\w_-]+)/;function B(i,e,t){if(!i.config||"windmill"!==i.config.container)return i;if("function"!=typeof i.requireModule)return i;var a=i.requireModule,s=t||g(function(){return e});return i.requireModule=function(e){var t="weex",n=e,r=q.exec(e);switch(r?(t=r[1],n=r[2]):"string"==typeof i.config.container&&(t=i.config.container),t){case"weex":return a.call(i,n);case"windmill":var o=s(n);return!o&&i.isRegisteredModule(n)?(h('Trying to call weex module "'+n+'" in windmill context!This is NOT a good practice, please use windmill module instead!'),a.call(i,n)):o;default:v('Failed to require scoped module "'+n+'", the "'+t+'" scope is unknown.')}},i}function U(s,c,e){var l={},n=e&&e.normalizeEventName||function(e){return e},r=!(!e||!e.noTriggerWorker);function o(e,t,n,r){void 0===r&&(r=!1);var o=c.getId();l[o]||(l[o]={});var i=l[o];if(i[e]||(i[e]=[]),i[e].push({handler:t,wrap:n}),r)return s.$once(e,n);s.$on(e,n)}var i={on:function(e,t){o(n(e),t,function(e){t.call(c.getVm(),e.data)})},once:function(e,t){o(n(e),t,function(e){t.call(c.getVm(),e.data)},!0)},off:function(e,t){!function(e,n){var t=c.getId(),r=l[t];if(!r)return h("Unbind event from page "+t+" with no event handlers.");var o,i,a=r[e];a?n?(a.forEach(function(e,t){e.handler===n&&(o=e,i=t)}),o&&o.wrap&&(a.splice(i,1),s.$off(e,o.wrap))):((l[t]||(l[t]={}))[e]=[],s.$off(e)):h("Unbind event '"+e+"' which has no event handler.")}(n(e),t)},emit:function(e,t){s.$emit(n(e),t),r&&s.$emit(e+"@"+c.getId(),t,"AppWorker")},call:"default"},a=function(){};return["on","off","emit","once","call"].reduce(function(e,t){var o,n="$"+t,r=i[t];return e[n]="function"==typeof r?r:"default"===r?(o=n,function(){for(var e=arguments,t=[],n=arguments.length;n--;)t[n]=e[n];var r=s[o];return r.apply(void 0,t)}):a,e},{})}var z="AppWorker";function H(e){switch(c(e)){case"Object":for(var t in e)H(e[t]);break;case"Array":e.forEach(H)}}return function(e){var a=e.createInstanceContext,t=Object.assign({},e);return t.createInstanceContext=function(e,t,n){var r=t&&t.weex;if(!r||"windmill"!==r.config.container)return a(e,t,n);var l,u,o=Object.assign({},a(e,t,n)),i=W(r);return o.weex=B(r,i),o.requireModule=function(e){return r.requireModule(e)},o.__vue_page__=(l=o,u=i,function(){function e(e,t){var n=this,r=t||l,o=r.Vue,i=r.weex,a=i.config,s=a.clientId,c=a.pageName;if(p("Create Page with id "+s+", pageName "+c+"."),this._id=i.config.clientId||null,this._name=i.config.pageName||null,this._vm=null,this._instanceContext=t||l,this._Vue=o,this._weex=i,this._windmill=u,this._hold=!1,this._options=e,this._state="function"==typeof e.data?e.data():e.data,e.data=function(){return n._state},o.prototype.$page=U(this._windmill,this),d("bind with $page: "+Object.keys(o.prototype.$page)),e._noLazy){p("Init vm instantly in Page constructor with no lazy.");try{this._initVm()}catch(e){v("[windmill-vue-renderer] init vm instantly failed: "+(e&&e.message))}}this._shakeHandsBeforeInit(),this._windmill.$once(w,this._onStateInit.bind(this))}return e.prototype.getVm=function(){return this._vm},e.prototype.getId=function(){return this._id},e.prototype._initVm=function(){var n=this,e=this._vm=new this._Vue(this._options),t=e.$options.data,r=0;e.$watch(function(){for(var e in t)H(t[e]);return r=(r+1)%2},function(e,t){n._hold?n._hold=!1:n._debouncedWatcherCb(e,t)},{sync:!0})},e.prototype._shakeHandsBeforeInit=function(){d("start handshaking with worker."),this._sendPageReady(),this._windmill.$once(_,this._onWorkerReady.bind(this))},e.prototype._sendPageReady=function(){d("Send "+b+" to worker."),this._windmill.$emit(b+"@"+this._id,{},z)},e.prototype._onWorkerReady=function(t){var n;try{n=JSON.stringify(t)}catch(e){n=t+""}d(_+" event received: "+n+".");var e=t.data,r=e.clientId,o=e.pageName;r&&(this._id=r),o&&(this._name=o),this._sendPageReady()},e.prototype._onStateInit=function(t){var n,r=this;try{n=JSON.stringify(t)}catch(e){n=t+""}d(w+" event received: "+n),this._windmill.$off(_),this._windmill.$on(S,this._onDataSync.bind(this));var e=t.data,o=t.origin,i=e.clientId,a=e.pageName,s=i||o;s&&(this._id=s),a&&(this._name=a),this._state=Object.assign(this._state||{},e.initialState||{}),this._windmill.$emit(k+"@"+this._id,{},z);var c=this._vm;if(d("debounce watcher callback for page data watcher binding."),this._debouncedWatcherCb=f(function(e,t){d("emit "+O+" event."),r._windmill.$emit(O+"@"+r._id,r._vm&&r._vm.$options.data,z)},1e3/60),c)this._mergeData(e);else try{p("Init vm after "+w+"."),this._initVm()}catch(e){v("[windmill-vue-renderer] "+(e&&e.message))}},e.prototype._onDataSync=function(t){var n;try{n=JSON.stringify(t)}catch(e){n=t+""}d(S+" event received: "+n);var e=t.data;this._mergeData(e,!0)},e.prototype._mergeData=function(e,t){void 0===t&&(t=!1);var n=this._vm,r=n.$options.data;for(var o in e)t&&(this._hold=!0),n.$set(r,o,e[o])},e}()),Object.freeze(o),o},t}}()});fi.Vue=yi(fi.Vue),function(e){var t=sr.init,n=sr.config;n.frameworks=e;var r=rn.native,o=rn.transformer;for(var i in pr)sr.service.register(i,pr[i]);sr.freezePrototype(),global.frameworkVersion=r,global.transformerVersion=o;var a=t(n),s=function(r){global[r]=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];var n=a[r].apply(a,e);return n instanceof Error&&console.error(n.toString()),n}};for(var c in a)s(c)}(fi),Object.freeze(Object),Object.freeze(Array),nn(pi=Object.prototype,"__defineGetter__",di="Object.prototype"),nn(pi,"__defineSetter__",di),nn(pi,"__lookupGetter__",di),nn(pi,"__lookupSetter__",di),nn(pi,"constructor",di),nn(pi,"hasOwnProperty",di),nn(pi,"isPrototypeOf",di),nn(pi,"propertyIsEnumerable",di),nn(pi,"toLocaleString",di),nn(pi,"toString",di),nn(pi,"valueOf",di),Object.seal(pi),Object.freeze(Array.prototype),Object.freeze(String.prototype),Object.freeze(Number.prototype),Object.freeze(Boolean.prototype),nn(hi=Error.prototype,"name",vi="Error.prototype"),nn(hi,"message",vi),nn(hi,"toString",vi),nn(hi,"constructor",vi),Object.seal(hi),Object.freeze(Date.prototype),Object.freeze(RegExp.prototype),global.registerMethods(mi)});
//# sourceMappingURL=weex-js-framework.min.js.map
diff --git a/android/sdk/build.gradle b/android/sdk/build.gradle
index 1dc2c19aaf..7dac40278b 100755
--- a/android/sdk/build.gradle
+++ b/android/sdk/build.gradle
@@ -65,10 +65,12 @@ checkstyle {
version = project.hasProperty('weexVersion')? project.getProperty('weexVersion') : "0.20.0.1"
android {
-
delete 'libs/armeabi/libweexcore.so'
delete 'libs/armeabi-v7a/libweexcore.so'
delete 'libs/x86/libweexcore.so'
+ delete 'libs/armeabi/libweexjss.so'
+ delete 'libs/armeabi-v7a/libweexjss.so'
+ delete 'libs/x86/libweexjss.so'
compileSdkVersion project.compileSdkVersion
buildToolsVersion project.buildToolsVersion
@@ -123,6 +125,15 @@ android {
def ARMEABI_Size = new File(projectDir,"libs/armeabi/libweexcore.so").length();
def ARMEABIV7_Size = new File(projectDir,"libs/armeabi-v7/libweexcore.so").length();
def X86_Size = new File(projectDir,"libs/x86/libweexcore.so").length();
+ def ndkversion = 16;
+ def api_level = "";
+ def compile_tool = "clang";
+ def cxx_stl = "c++_static";
+ if (ndkversion < 16) {
+ api_level = "android-14";
+ } else {
+ api_level = "android-19";
+ }
println "ARMEABI_Size: "+ARMEABI_Size;
println "ARMEABIV7_Size:" + ARMEABIV7_Size;
println "X86_Size:" + X86_Size;
@@ -146,10 +157,11 @@ android {
externalNativeBuild {
cmake {
- arguments '-DANDROID_PLATFORM=android-14',
- '-DANDROID_TOOLCHAIN=gcc',
- '-DANDROID_STL=gnustl_static',
- '-DCMAKE_BUILD_TYPE=Release'
+ arguments '-DANDROID_PLATFORM='+"${api_level}",
+ '-DANDROID_TOOLCHAIN='+"${compile_tool}",
+ '-DANDROID_STL='+"${cxx_stl}",
+ '-DCMAKE_BUILD_TYPE=Release',
+ '-DENABLE_ASAN=false'
}
}
}
@@ -358,4 +370,4 @@ bintray {
name = project.version
}
}
-}
\ No newline at end of file
+}
diff --git a/android/sdk/libs/armeabi-v7a/libJavaScriptCore.so b/android/sdk/libs/armeabi-v7a/libJavaScriptCore.so
index d530580c4d..03deedb522 100755
Binary files a/android/sdk/libs/armeabi-v7a/libJavaScriptCore.so and b/android/sdk/libs/armeabi-v7a/libJavaScriptCore.so differ
diff --git a/android/sdk/libs/armeabi-v7a/libWTF.so b/android/sdk/libs/armeabi-v7a/libWTF.so
new file mode 100755
index 0000000000..790bef24ae
Binary files /dev/null and b/android/sdk/libs/armeabi-v7a/libWTF.so differ
diff --git a/android/sdk/libs/armeabi-v7a/libweexjss.so b/android/sdk/libs/armeabi-v7a/libweexjss.so
old mode 100755
new mode 100644
index 8bab6c1f7e..9ca7221909
Binary files a/android/sdk/libs/armeabi-v7a/libweexjss.so and b/android/sdk/libs/armeabi-v7a/libweexjss.so differ
diff --git a/android/sdk/libs/armeabi/libJavaScriptCore.so b/android/sdk/libs/armeabi/libJavaScriptCore.so
index d530580c4d..03deedb522 100755
Binary files a/android/sdk/libs/armeabi/libJavaScriptCore.so and b/android/sdk/libs/armeabi/libJavaScriptCore.so differ
diff --git a/android/sdk/libs/armeabi/libWTF.so b/android/sdk/libs/armeabi/libWTF.so
new file mode 100755
index 0000000000..790bef24ae
Binary files /dev/null and b/android/sdk/libs/armeabi/libWTF.so differ
diff --git a/android/sdk/libs/armeabi/libweexjss.so b/android/sdk/libs/armeabi/libweexjss.so
old mode 100755
new mode 100644
index 8bab6c1f7e..9853537086
Binary files a/android/sdk/libs/armeabi/libweexjss.so and b/android/sdk/libs/armeabi/libweexjss.so differ
diff --git a/android/sdk/libs/x86/libJavaScriptCore.so b/android/sdk/libs/x86/libJavaScriptCore.so
old mode 100644
new mode 100755
index 0e0f9f5ed7..b7abc27353
Binary files a/android/sdk/libs/x86/libJavaScriptCore.so and b/android/sdk/libs/x86/libJavaScriptCore.so differ
diff --git a/android/sdk/libs/x86/libWTF.so b/android/sdk/libs/x86/libWTF.so
new file mode 100755
index 0000000000..0f4c2df6f3
Binary files /dev/null and b/android/sdk/libs/x86/libWTF.so differ
diff --git a/android/sdk/libs/x86/libweexjss.so b/android/sdk/libs/x86/libweexjss.so
index 67d67944f7..f960b900c2 100644
Binary files a/android/sdk/libs/x86/libweexjss.so and b/android/sdk/libs/x86/libweexjss.so differ
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/jni/NativeRenderObjectUtils.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/jni/NativeRenderObjectUtils.java
index f665e8b18f..12f125a44e 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/jni/NativeRenderObjectUtils.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/jni/NativeRenderObjectUtils.java
@@ -63,7 +63,7 @@
public static native boolean nativeRenderObjectHasNewLayout(long ptr);
public static native int nativeRenderObjectChildCount(long ptr);
public static native long nativeRenderObjectGetChild(long ptr, int index);
- public static native long nativeRenderObjectUpdateComponent(long ptr, WXComponent component);
+ public static native void nativeRenderObjectUpdateComponent(long ptr, WXComponent component);
public static native void nativeRenderObjectChildWaste(long ptr, boolean waster);
diff --git a/ios/playground/WeexDemo.xcodeproj/project.pbxproj b/ios/playground/WeexDemo.xcodeproj/project.pbxproj
index 1dd2b43b98..0d64451b25 100644
--- a/ios/playground/WeexDemo.xcodeproj/project.pbxproj
+++ b/ios/playground/WeexDemo.xcodeproj/project.pbxproj
@@ -392,7 +392,6 @@
775BEE781C1E8ECC008D1629 /* Frameworks */,
775BEE791C1E8ECC008D1629 /* Resources */,
C715566148067A7FFAB7797D /* [CP] Copy Pods Resources */,
- ED72EE9F9A66E17E73D6C3BC /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -430,7 +429,6 @@
84361D3C1CA10F8E00F43825 /* Frameworks */,
84361D431CA10F8E00F43825 /* Resources */,
84361D6F1CA10F8E00F43825 /* [CP] Copy Pods Resources */,
- EC0A67104CF45CC2B03DF0BE /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -542,7 +540,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
84361D6F1CA10F8E00F43825 /* [CP] Copy Pods Resources */ = {
@@ -592,7 +590,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
C715566148067A7FFAB7797D /* [CP] Copy Pods Resources */ = {
@@ -627,36 +625,6 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-WeexDemo/Pods-WeexDemo-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- EC0A67104CF45CC2B03DF0BE /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Embed Pods Frameworks";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-WeexUITestDemo/Pods-WeexUITestDemo-frameworks.sh\"\n";
- showEnvVarsInLog = 0;
- };
- ED72EE9F9A66E17E73D6C3BC /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Embed Pods Frameworks";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-WeexDemo/Pods-WeexDemo-frameworks.sh\"\n";
- showEnvVarsInLog = 0;
- };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
diff --git a/ios/playground/WeexDemo/AppDelegate.m b/ios/playground/WeexDemo/AppDelegate.m
index 7a5bbcdc5a..25a6b95fc4 100644
--- a/ios/playground/WeexDemo/AppDelegate.m
+++ b/ios/playground/WeexDemo/AppDelegate.m
@@ -39,7 +39,6 @@
#import "WXWebSocketDefaultImpl.h"
#import <WeexPluginLoader/WeexPluginLoader.h>
-
#ifdef DEBUG
#import "DebugAnalyzer.h"
#endif
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
index c67f1bc98d..1e2c331e33 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
@@ -31,7 +31,8 @@
#import "WXSDKEngine.h"
#import "WXAppMonitorProtocol.h"
-#include "base/CoreConstants.h"
+#include "base/core_constants.h"
+#include "base/time_utils.h"
#include "core/manager/weex_core_manager.h"
#include "core/render/manager/render_manager.h"
#include "core/render/page/render_page.h"
@@ -43,7 +44,6 @@
#include "core/data_render/vnode/vnode_render_manager.h"
#include "core/bridge/platform/core_side_in_platform.h"
#include "core/bridge/script/core_side_in_script.h"
-#include "base/TimeUtils.h"
#include "core/network/http_module.h"
#import <objc/runtime.h>
diff --git a/weex_core/CMakeLists.txt b/weex_core/CMakeLists.txt
index b0dfca0dcf..2894e59436 100644
--- a/weex_core/CMakeLists.txt
+++ b/weex_core/CMakeLists.txt
@@ -1,21 +1,3 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
cmake_minimum_required(VERSION 3.4.1)
project(WeexCore)
add_subdirectory(Source)
diff --git a/weex_core/Source/CMakeLists.txt b/weex_core/Source/CMakeLists.txt
index f3e5019aa4..c535fc780b 100644
--- a/weex_core/Source/CMakeLists.txt
+++ b/weex_core/Source/CMakeLists.txt
@@ -1,23 +1,6 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
cmake_minimum_required(VERSION 3.4.1)
set(WEEXCORE_LIBRARY_NAME weexcore)
+set(WEEX_CORE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
message("${ANDROID_STL} ")
if ("${ANDROID_STL}" STREQUAL "c++_static")
@@ -31,7 +14,6 @@ add_compile_options(-fexceptions)
add_definitions(-DGNU_SUPPORT=1)
add_definitions(-DJSONCPP_NO_LOCALE_SUPPORT=1)
add_definitions(-DDEBUG=1)
-add_definitions(-DOS_ANDROID=1)
add_definitions(-DRENDER_LOG=0)
add_definitions(-DPERFORMANCE_LOG=0)
@@ -39,14 +21,19 @@ add_definitions(-DLAYOUT_LOG=0)
add_definitions(-DJSAPI_LOG=0)
add_definitions(-DDOM_PARSER_LOG=0)
+set(LOCAL_LIBRARIES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs/${ANDROID_ABI})
+
+if ("${ANDROID_ABI}" STREQUAL "x86")
+ # todo
+else ()
+ if ("${ENABLE_ASAN}" STREQUAL "true")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -g3 -fPIC")
+ endif ()
+endif ()
+
+add_compile_options(-fexceptions)
+
set(COMMON_SRCS
- ./base/time_point.cc
- ./base/thread/thread_impl_posix.cc
- ./base/thread/thread_impl_android.cc
- ./base/message_loop/message_loop.cc
- ./base/message_loop/message_pump_posix.cc
- ./base/message_loop/message_pump_android.cc
- ./base/third_party/icu/icu_utf.cpp
./core/render/manager/render_manager.cpp
./core/render/page/render_page.cpp
@@ -91,12 +78,7 @@ set(COMMON_SRCS
./core/data_render/class_array.cc
./core/data_render/class_json.cc
./core/data_render/class_string.cc
- ./core/data_render/class_regex.cc
- ./core/data_render/class_console.cc
- ./core/data_render/class_window.cc
- ./core/data_render/class_math.cc
./core/data_render/class_factory.cc
- ./core/data_render/class_function.cc
./core/data_render/class_object.cc
./core/data_render/code_generator.cc
./core/data_render/exec_state.cc
@@ -115,43 +97,48 @@ set(COMMON_SRCS
./core/data_render/table.cc
./core/data_render/token.cc
./core/data_render/tokenizer.cc
- ./core/data_render/op_code.cc
./core/data_render/vm.cc
+ ./core/data_render/binary_file.cc
+ ./core/data_render/class_console.cc
+ ./core/data_render/class_function.cc
+ ./core/data_render/class_math.cc
+ ./core/data_render/class_regex.cc
+ ./core/data_render/class_window.cc
./core/data_render/exec_state_binary.cc
./core/data_render/exec_state_section.cc
+ ./core/data_render/op_code.cc
./core/data_render/vnode/vnode.cc
./core/data_render/vnode/vcomponent.cc
./core/data_render/vnode/vnode_exec_env.cc
./core/data_render/vnode/vnode_render_manager.cc
./core/data_render/vnode/vnode_render_context.cc
-
./core/network/http_module.cc
)
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/base)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/wson)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wson)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/third_party/json11)
+#link_directories(${LOCAL_LIBRARIES_DIR})
SET(FINAL_ADD_LIBRARY
${COMMON_SRCS}
)
SET(FINAL_TARGET_LINK_LIBRARIES wson json11)
-if (ANDROID)
+if(ANDROID)
+ add_definitions(-DOS_ANDROID=1)
## add_subdirectory for subdirectory has a CMakeLists.txt
- add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/IPC)
+ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/third_party/IPC)
+ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/android/jsengine)
## include_directories for include head file
- include_directories(${CMAKE_CURRENT_SOURCE_DIR}/IPC)
+ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/IPC)
set (ANDROID_SRCS
- ./android/jniprebuild/jni_load.cc
- ./android/base/jni/android_jni.cpp
- ./android/base/jni/jbytearray_ref.cpp
- ./android/base/jni/scoped_java_ref.cpp
- ./android/base/base64/base64.cpp
- ./android/base/base64/modp_base64/modp_b64.cc
- ./android/base/string/scoped_jstring.cpp
+ ./android/weex_extend_js_api.h
+ ./android/weex_extend_js_api.cpp
./android/base/string/scoped_jstring_utf8.cpp
./android/base/string/jstring_cache.cpp
+ ./android/base/string/scoped_jstring.cpp
./android/wrap/content_box_measurement_impl_android.cpp
./android/wrap/wx_debug_js_bridge.cpp
./android/wrap/native_render_object_utils_impl_android.cpp
@@ -168,23 +155,20 @@ if (ANDROID)
./android/utils/cache_utils.cpp
./android/utils/params_utils.cpp
./android/utils/so_utils.cpp
- ./android/utils/IPCStringResult.cpp
+ ./android/utils/ipc_string_result.cpp
./android/wrap/log_utils.cpp
./android/wrap/hash_set.cpp
./android/wrap/wx_map.cpp
./android/wrap/wx_js_object.cpp
./android/wrap/wx_bridge.cpp
./android/wrap/wx_params.cpp
- ./android/base/jni_type.cpp
+ ./android/multiprocess/weex_js_connection.cpp
+ ./android/utils/jni_load.cc
./core/data_render/vnode/android/vcomponent_lifecycle_listener.cc
./core/data_render/vnode/android/vnode_on_event_listener.cc
./core/data_render/vnode/android/conversion.cc
./core/network/android/default_request_handler.cc
-
- ./android/jsengine/multiprocess/WeexJSConnection.cpp
- ./android/jsengine/multiprocess/ExtendJSApi.cpp
-
)
SET(FINAL_ADD_LIBRARY
${FINAL_ADD_LIBRARY}
@@ -193,19 +177,20 @@ if (ANDROID)
SET(FINAL_TARGET_LINK_LIBRARIES
${FINAL_TARGET_LINK_LIBRARIES}
+ weexbase
wson
android
weexipc
+ #weexjss
log
+ c
z
)
+endif(ANDROID)
-endif (ANDROID)
-
-##if(iOS)
- add_definitions(-DTARGET_OS_IPHONE=1)
-
-##endif(iOS)
+#if(iOS)
+#add_definitions(-DTARGET_OS_IPHONE=1)
+#endif(iOS)
add_library(${WEEXCORE_LIBRARY_NAME} SHARED ${FINAL_ADD_LIBRARY})
diff --git a/weex_core/Source/IPC/Buffering/IPCBuffer.h b/weex_core/Source/IPC/Buffering/IPCBuffer.h
deleted file mode 100644
index 01ab27f0ce..0000000000
--- a/weex_core/Source/IPC/Buffering/IPCBuffer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Implementation of the user-space ashmem API for devices, which have our
- * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
- * used by the simulator.
- */
-
-#ifndef IPCBUFFER_H
-#define IPCBUFFER_H
-#include <stddef.h>
-
-// A buffer starts with msg.
-class IPCBuffer {
-public:
- virtual ~IPCBuffer() = default;
- virtual const void* get() = 0;
- virtual size_t length() = 0;
-};
-
-#endif /* IPCBUFFER_H */
diff --git a/weex_core/Source/IPC/IPCByteArray.h b/weex_core/Source/IPC/IPCByteArray.h
deleted file mode 100644
index e38b403ec5..0000000000
--- a/weex_core/Source/IPC/IPCByteArray.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Implementation of the user-space ashmem API for devices, which have our
- * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
- * used by the simulator.
- */
-
-#ifndef IPCBYTEARRAY_H
-#define IPCBYTEARRAY_H
-#include <stddef.h>
-struct IPCByteArray {
- uint32_t length;
- char content[1];
-};
-#endif /* IPCBYTEARRAY_H */
diff --git a/weex_core/Source/IPC/IPCCheck.cpp b/weex_core/Source/IPC/IPCCheck.cpp
deleted file mode 100644
index d5d54f102b..0000000000
--- a/weex_core/Source/IPC/IPCCheck.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Implementation of the user-space ashmem API for devices, which have our
- * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
- * used by the simulator.
- */
-
-#if !defined(NDEBUG)
-#include "IPCCheck.h"
-#include <android/log.h>
-#define TAG "linzj_IPC"
-
-void reportCheckFailed(const char* msg, const char* file, int line)
-{
- __android_log_print(ANDROID_LOG_ERROR, TAG, msg, file, line);
- __builtin_trap();
-}
-
-void reportUnreachable(const char* file, int line)
-{
- __android_log_print(ANDROID_LOG_ERROR, TAG, "unreachable statement reached %s %d", file, line);
- __builtin_trap();
-}
-#endif
diff --git a/weex_core/Source/IPC/IPCException.cpp b/weex_core/Source/IPC/IPCException.cpp
deleted file mode 100644
index 22b5790459..0000000000
--- a/weex_core/Source/IPC/IPCException.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Implementation of the user-space ashmem API for devices, which have our
- * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
- * used by the simulator.
- */
-
-#include "IPCException.h"
-#include <stdarg.h>
-#include <string>
-
-struct IPCException::IPCExceptionImpl {
- std::string str;
-};
-
-IPCException::IPCException(const char* fmt, ...)
- : m_impl(new IPCExceptionImpl)
-{
- va_list ap;
- char buffer[256];
- va_start(ap, fmt);
- vsnprintf(buffer, 256, fmt, ap);
- va_end(ap);
- m_impl->str.assign(buffer);
-}
-
-IPCException::~IPCException()
-{
-}
-
-IPCException::IPCException(IPCException&& ex)
-{
- m_impl = std::move(ex.m_impl);
-}
-
-const char* IPCException::msg() const
-{
- return m_impl->str.c_str();
-}
diff --git a/weex_core/Source/IPC/IPCException.h b/weex_core/Source/IPC/IPCException.h
deleted file mode 100644
index a53312ee3f..0000000000
--- a/weex_core/Source/IPC/IPCException.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Implementation of the user-space ashmem API for devices, which have our
- * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
- * used by the simulator.
- */
-
-#ifndef IPCEXCEPTION_H
-#define IPCEXCEPTION_H
-#include <memory>
-
-class IPCException {
-public:
- IPCException(const char* fmt, ...);
- ~IPCException();
- IPCException(IPCException&& ex);
- const char* msg() const;
-
-private:
- struct IPCExceptionImpl;
- std::unique_ptr<IPCExceptionImpl> m_impl;
-};
-#endif /* IPCEXCEPTION_H */
diff --git a/weex_core/Source/IPC/IPCHandler.h b/weex_core/Source/IPC/IPCHandler.h
deleted file mode 100644
index 8fab6b1576..0000000000
--- a/weex_core/Source/IPC/IPCHandler.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Implementation of the user-space ashmem API for devices, which have our
- * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
- * used by the simulator.
- */
-
-#ifndef IPCHANDLER_H
-#define IPCHANDLER_H
-#include <functional>
-#include <memory>
-#include <stdint.h>
-
-class IPCResult;
-class IPCArguments;
-
-class IPCHandler {
-public:
- virtual ~IPCHandler() = default;
- virtual std::unique_ptr<IPCResult> handle(uint32_t msg, IPCArguments*) = 0;
- virtual void registerHandler(int msg, const std::function<std::unique_ptr<IPCResult>(IPCArguments*)>& handler) = 0;
-};
-
-std::unique_ptr<IPCHandler> createIPCHandler();
-#endif /* IPCHANDLER_H */
diff --git a/weex_core/Source/IPC/IPCListener.h b/weex_core/Source/IPC/IPCListener.h
deleted file mode 100644
index de5f1a4f9e..0000000000
--- a/weex_core/Source/IPC/IPCListener.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Implementation of the user-space ashmem API for devices, which have our
- * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
- * used by the simulator.
- */
-
-#ifndef IPCLISTENER_H
-#define IPCLISTENER_H
-#include <memory>
-class IPCHandler;
-class IPCFutexPageQueue;
-
-class IPCListener {
-public:
- virtual ~IPCListener() = default;
- virtual void listen() = 0;
-};
-
-std::unique_ptr<IPCListener> createIPCListener(IPCFutexPageQueue*, IPCHandler* handler);
-#endif /* IPCLISTENER_H */
diff --git a/weex_core/Source/IPC/IPCLog.h b/weex_core/Source/IPC/IPCLog.h
deleted file mode 100644
index 94b0b5a3c1..0000000000
--- a/weex_core/Source/IPC/IPCLog.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Implementation of the user-space ashmem API for devices, which have our
- * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
- * used by the simulator.
- */
-
-#ifndef IPCLOG_H
-#define IPCLOG_H
-#include <android/log.h>
-#define TAG "linzj_IPC"
-#define IPC_LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
-
-#if defined(ENABLE_IPC_DEBUG_LOG) && ENABLE_IPC_DEBUG_LOG
-#define IPC_LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
-#else
-#define IPC_LOGD(...)
-#endif
-#endif /* IPCLOG_H */
diff --git a/weex_core/Source/IPC/IPCSender.h b/weex_core/Source/IPC/IPCSender.h
deleted file mode 100644
index 3c70aecd62..0000000000
--- a/weex_core/Source/IPC/IPCSender.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Implementation of the user-space ashmem API for devices, which have our
- * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
- * used by the simulator.
- */
-
-#ifndef IPCSENDER_H
-#define IPCSENDER_H
-#include <memory>
-class IPCBuffer;
-class IPCResult;
-class IPCHandler;
-class IPCFutexPageQueue;
-
-class IPCSender {
-public:
- virtual ~IPCSender() = default;
- virtual std::unique_ptr<IPCResult> send(IPCBuffer* buffer) = 0;
-};
-std::unique_ptr<IPCSender> createIPCSender(IPCFutexPageQueue*, IPCHandler* handler);
-#endif /* IPCSENDER_H */
diff --git a/weex_core/Source/IPC/IPCString.h b/weex_core/Source/IPC/IPCString.h
deleted file mode 100644
index f103827781..0000000000
--- a/weex_core/Source/IPC/IPCString.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Implementation of the user-space ashmem API for devices, which have our
- * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
- * used by the simulator.
- */
-
-#ifndef IPCSTRING_H
-#define IPCSTRING_H
-struct IPCString {
- uint32_t length;
- uint16_t content[1];
-};
-#endif /* IPCSTRING_H */
diff --git a/weex_core/Source/android/base/base64/base64.cpp b/weex_core/Source/android/base/base64/base64.cpp
deleted file mode 100644
index c70d2c4799..0000000000
--- a/weex_core/Source/android/base/base64/base64.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * \file
- * <PRE>
- * High performance base64 encoder / decoder
- * Version 1.3 -- 17-Mar-2006
- *
- * Copyright © 2005, 2006, Nick Galbreath -- nickg [at] modp [dot] com
- * All rights reserved.
- *
- * http://modp.com/release/base64
- *
- * Released under bsd license. See modp_b64.c for details.
- * </pre>
- *
- * The default implementation is the standard b64 encoding with padding.
- * It's easy to change this to use "URL safe" characters and to remove
- * padding. See the modp_b64.c source code for details.
- *
- */
-
-#include "./base64.h"
-#include <string.h>
-
-bool Base64Encode(const std::string &input, std::string *output) {
- std::string temp;
- temp.resize(modp_b64_encode_len(input.size())); // makes room for null byte
-
- // null terminates result since result is base64 text!
- int input_size = static_cast<int>(input.size());
- int output_size = modp_b64_encode(&(temp[0]), input.data(), input_size);
- if (output_size < 0)
- return false;
-
- temp.resize(output_size); // strips off null byte
- output->swap(temp);
- return true;
-}
-
-bool Base64Decode(const std::string &input, std::string *output) {
- std::string temp;
- temp.resize(modp_b64_decode_len(input.size()));
-
- // does not null terminate result since result is binary data!
- int input_size = static_cast<int>(input.size());
- int output_size = modp_b64_decode(&(temp[0]), input.data(), input_size);
- if (output_size < 0)
- return false;
-
- temp.resize(output_size);
- output->swap(temp);
- return true;
-}
\ No newline at end of file
diff --git a/weex_core/Source/android/base/base64/base64.h b/weex_core/Source/android/base/base64/base64.h
deleted file mode 100644
index 1380dd154d..0000000000
--- a/weex_core/Source/android/base/base64/base64.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * \file
- * <PRE>
- * High performance base64 encoder / decoder
- * Version 1.3 -- 17-Mar-2006
- *
- * Copyright © 2005, 2006, Nick Galbreath -- nickg [at] modp [dot] com
- * All rights reserved.
- *
- * http://modp.com/release/base64
- *
- * Released under bsd license. See modp_b64.c for details.
- * </pre>
- *
- * The default implementation is the standard b64 encoding with padding.
- * It's easy to change this to use "URL safe" characters and to remove
- * padding. See the modp_b64.c source code for details.
- *
- */
-
-#include "./modp_base64/modp_b64.h"
-
-// Encodes the input string in base64. Returns true if successful and false
-// otherwise. The output string is only modified if successful.
-bool Base64Encode(const std::string &input, std::string *output);
-
-// Decodes the base64 input string. Returns true if successful and false
-// otherwise. The output string is only modified if successful.
-bool Base64Decode(const std::string &input, std::string *output);
diff --git a/weex_core/Source/android/base/base64/modp_base64/modp_b64.cc b/weex_core/Source/android/base/base64/modp_base64/modp_b64.cc
deleted file mode 100644
index 03cf6eaca2..0000000000
--- a/weex_core/Source/android/base/base64/modp_base64/modp_b64.cc
+++ /dev/null
@@ -1,241 +0,0 @@
-/**
- * \file
- * <PRE>
- * High performance base64 encoder / decoder
- * Version 1.3 -- 17-Mar-2006
- *
- * Copyright © 2005, 2006, Nick Galbreath -- nickg [at] modp [dot] com
- * All rights reserved.
- *
- * http://modp.com/release/base64
- *
- * Released under bsd license. See modp_b64.c for details.
- * </pre>
- *
- * The default implementation is the standard b64 encoding with padding.
- * It's easy to change this to use "URL safe" characters and to remove
- * padding. See the modp_b64.c source code for details.
- *
- */
-
-/* public header */
-#include "modp_b64.h"
-
-/*
- * If you are ripping this out of the library, comment out the next
- * line and uncomment the next lines as approrpiate
- */
-//#include "config.h"
-
-/* if on motoral, sun, ibm; uncomment this */
-/* #define WORDS_BIGENDIAN 1 */
-/* else for Intel, Amd; uncomment this */
-/* #undef WORDS_BIGENDIAN */
-
-#include "modp_b64_data.h"
-
-#define BADCHAR 0x01FFFFFF
-
-/**
- * you can control if we use padding by commenting out this
- * next line. However, I highly recommend you use padding and not
- * using it should only be for compatability with a 3rd party.
- * Also, 'no padding' is not tested!
- */
-#define DOPAD 1
-
-/*
- * if we aren't doing padding
- * set the pad character to NULL
- */
-#ifndef DOPAD
-#undef CHARPAD
-#define CHARPAD '\0'
-#endif
-
-int modp_b64_encode(char *dest, const char *str, int len) {
- int i;
- uint8_t *p = (uint8_t *) dest;
-
- /* unsigned here is important! */
- uint8_t t1, t2, t3;
-
- for (i = 0; i < len - 2; i += 3) {
- t1 = str[i];
- t2 = str[i + 1];
- t3 = str[i + 2];
- *p++ = e0[t1];
- *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
- *p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)];
- *p++ = e2[t3];
- }
-
- switch (len - i) {
- case 0:
- break;
- case 1:
- t1 = str[i];
- *p++ = e0[t1];
- *p++ = e1[(t1 & 0x03) << 4];
- *p++ = CHARPAD;
- *p++ = CHARPAD;
- break;
- default: /* case 2 */
- t1 = str[i];
- t2 = str[i + 1];
- *p++ = e0[t1];
- *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
- *p++ = e2[(t2 & 0x0F) << 2];
- *p++ = CHARPAD;
- }
-
- *p = '\0';
- return p - (uint8_t *) dest;
-}
-
-#ifdef WORDS_BIGENDIAN /* BIG ENDIAN -- SUN / IBM / MOTOROLA */
-int modp_b64_decode(char* dest, const char* src, int len)
-{
- if (len == 0) return 0;
-
-#ifdef DOPAD
- /* if padding is used, then the message must be at least
- 4 chars and be a multiple of 4.
- there can be at most 2 pad chars at the end */
- if (len < 4 || (len % 4 != 0)) return -1;
- if (src[len-1] == CHARPAD) {
- len--;
- if (src[len -1] == CHARPAD) {
- len--;
- }
- }
-#endif /* DOPAD */
-
- int i;
- int leftover = len % 4;
- int chunks = (leftover == 0) ? len / 4 - 1 : len /4;
-
- uint8_t* p = (uint8_t*) dest;
- uint32_t x = 0;
- uint32_t* destInt = (uint32_t*) p;
- uint32_t* srcInt = (uint32_t*) src;
- uint32_t y = *srcInt++;
- for (i = 0; i < chunks; ++i) {
- x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] |
- d2[y >> 8 & 0xff] | d3[y & 0xff];
-
- if (x >= BADCHAR) return -1;
- *destInt = x << 8;
- p += 3;
- destInt = (uint32_t*)p;
- y = *srcInt++;
- }
-
- switch (leftover) {
- case 0:
- x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] |
- d2[y >> 8 & 0xff] | d3[y & 0xff];
- if (x >= BADCHAR) return -1;
- *p++ = ((uint8_t*)&x)[1];
- *p++ = ((uint8_t*)&x)[2];
- *p = ((uint8_t*)&x)[3];
- return (chunks+1)*3;
- case 1:
- x = d3[y >> 24];
- *p = (uint8_t)x;
- break;
- case 2:
- x = d3[y >> 24] *64 + d3[(y >> 16) & 0xff];
- *p = (uint8_t)(x >> 4);
- break;
- default: /* case 3 */
- x = (d3[y >> 24] *64 + d3[(y >> 16) & 0xff])*64 +
- d3[(y >> 8) & 0xff];
- *p++ = (uint8_t) (x >> 10);
- *p = (uint8_t) (x >> 2);
- break;
- }
-
- if (x >= BADCHAR) return -1;
- return 3*chunks + (6*leftover)/8;
-}
-
-#else /* LITTLE ENDIAN -- INTEL AND FRIENDS */
-
-int modp_b64_decode(char *dest, const char *src, int len) {
- if (len == 0) return 0;
-
-#ifdef DOPAD
- /*
- * if padding is used, then the message must be at least
- * 4 chars and be a multiple of 4
- */
- if (len < 4 || (len % 4 != 0)) return -1; /* error */
- /* there can be at most 2 pad chars at the end */
- if (src[len - 1] == CHARPAD) {
- len--;
- if (src[len - 1] == CHARPAD) {
- len--;
- }
- }
-#endif
-
- int i;
- int leftover = len % 4;
- int chunks = (leftover == 0) ? len / 4 - 1 : len / 4;
-
- uint8_t *p = (uint8_t *) dest;
- uint32_t x = 0;
- uint32_t *destInt = (uint32_t *) p;
- uint32_t *srcInt = (uint32_t *) src;
- uint32_t y = *srcInt++;
- for (i = 0; i < chunks; ++i) {
- x = d0[y & 0xff] |
- d1[(y >> 8) & 0xff] |
- d2[(y >> 16) & 0xff] |
- d3[(y >> 24) & 0xff];
-
- if (x >= BADCHAR) return -1;
- *destInt = x;
- p += 3;
- destInt = (uint32_t *) p;
- y = *srcInt++;
- }
-
-
- switch (leftover) {
- case 0:
- x = d0[y & 0xff] |
- d1[(y >> 8) & 0xff] |
- d2[(y >> 16) & 0xff] |
- d3[(y >> 24) & 0xff];
-
- if (x >= BADCHAR) return -1;
- *p++ = ((uint8_t *) (&x))[0];
- *p++ = ((uint8_t *) (&x))[1];
- *p = ((uint8_t *) (&x))[2];
- return (chunks + 1) * 3;
- break;
- case 1: /* with padding this is an impossible case */
- x = d0[y & 0xff];
- *p = *((uint8_t *) (&x)); // i.e. first char/byte in int
- break;
- case 2: // * case 2, 1 output byte */
- x = d0[y & 0xff] | d1[y >> 8 & 0xff];
- *p = *((uint8_t *) (&x)); // i.e. first char
- break;
- default: /* case 3, 2 output bytes */
- x = d0[y & 0xff] |
- d1[y >> 8 & 0xff] |
- d2[y >> 16 & 0xff]; /* 0x3c */
- *p++ = ((uint8_t *) (&x))[0];
- *p = ((uint8_t *) (&x))[1];
- break;
- }
-
- if (x >= BADCHAR) return -1;
-
- return 3 * chunks + (6 * leftover) / 8;
-}
-
-#endif /* if bigendian / else / endif */
diff --git a/weex_core/Source/android/base/string/scoped_jstring.h b/weex_core/Source/android/base/string/scoped_jstring.h
index e2a5fd4747..1204a113a4 100644
--- a/weex_core/Source/android/base/string/scoped_jstring.h
+++ b/weex_core/Source/android/base/string/scoped_jstring.h
@@ -19,8 +19,8 @@
#ifndef _SCOPED_JSTRING_H_
#define _SCOPED_JSTRING_H_
-#include "../base64/base64.h"
#include <jni.h>
+#include "base/base64/base64.h"
namespace WeexCore {
diff --git a/weex_core/Source/android/base/string/scoped_jstring_utf8.h b/weex_core/Source/android/base/string/scoped_jstring_utf8.h
index fa739ba405..67901244c6 100644
--- a/weex_core/Source/android/base/string/scoped_jstring_utf8.h
+++ b/weex_core/Source/android/base/string/scoped_jstring_utf8.h
@@ -19,14 +19,14 @@
#ifndef _SCOPED_JSTRING_UTF_8_H_
#define _SCOPED_JSTRING_UTF_8_H_
-#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <type_traits>
-#include "../base64/base64.h"
#include <jni.h>
+#include "base/base64/base64.h"
+
namespace WeexCore {
class ScopedJStringUTF8 {
diff --git a/weex_core/Source/android/base/string/string_utils.h b/weex_core/Source/android/base/string/string_utils.h
index 6b42baec8e..b4fd777dc1 100644
--- a/weex_core/Source/android/base/string/string_utils.h
+++ b/weex_core/Source/android/base/string/string_utils.h
@@ -20,17 +20,18 @@
#define _STRING_UTILS_H_
#include <jni.h>
-#include <IPC/IPCArguments.h>
-#include <IPC/Serializing/IPCSerializer.h>
-#include <IPC/IPCString.h>
-#include <IPC/IPCByteArray.h>
#include <malloc.h>
-#include "scoped_jstring.h"
-#include "scoped_jstring_utf8.h"
#include <iostream>
#include <sstream>
#include <string>
+#include "scoped_jstring.h"
+#include "scoped_jstring_utf8.h"
+#include "third_party/IPC/IPCArguments.h"
+#include "third_party/IPC/Serializing/IPCSerializer.h"
+#include "third_party/IPC/IPCString.h"
+#include "third_party/IPC/IPCByteArray.h"
+
namespace WeexCore {
static inline std::string jString2Str(JNIEnv *env, const jstring &jstr) {
diff --git a/weex_core/Source/android/bridge/multi_process_and_so_initializer.cpp b/weex_core/Source/android/bridge/multi_process_and_so_initializer.cpp
index 51a09ec584..a16e31c31a 100644
--- a/weex_core/Source/android/bridge/multi_process_and_so_initializer.cpp
+++ b/weex_core/Source/android/bridge/multi_process_and_so_initializer.cpp
@@ -18,14 +18,16 @@
*/
#include "multi_process_and_so_initializer.h"
-#include <Buffering/IPCBuffer.h>
-#include <IPCException.h>
-#include <IPCHandler.h>
-#include <IPCResult.h>
-#include <Serializing/IPCSerializer.h>
-#include <android/base/log_utils.h>
-#include <android/jsengine/multiprocess/ExtendJSApi.h>
-#include <android/jsengine/multiprocess/WeexJSConnection.h>
+
+#include "android/weex_extend_js_api.h"
+#include "android/multiprocess/weex_js_connection.h"
+#include "base/android/log_utils.h"
+#include "third_party/IPC/Buffering/IPCBuffer.h"
+#include "third_party/IPC/IPCException.h"
+#include "third_party/IPC/IPCHandler.h"
+#include "third_party/IPC/IPCResult.h"
+#include "third_party/IPC/Serializing/IPCSerializer.h"
+
namespace WeexCore {
@@ -65,4 +67,4 @@ bool MultiProcessAndSoInitializer::Init(const std::function<void(IPCHandler*)>&
}
return true;
}
-} // namespace WeexCore
\ No newline at end of file
+} // namespace WeexCore
diff --git a/weex_core/Source/android/bridge/multi_so_initializer.cpp b/weex_core/Source/android/bridge/multi_so_initializer.cpp
index fe70dd3d7b..7014f3ddaf 100644
--- a/weex_core/Source/android/bridge/multi_so_initializer.cpp
+++ b/weex_core/Source/android/bridge/multi_so_initializer.cpp
@@ -18,10 +18,12 @@
*/
#include "multi_so_initializer.h"
-#include <android/base/log_utils.h>
-#include <android/utils/so_utils.h>
+
#include <dlfcn.h>
+#include "android/utils/so_utils.h"
+#include "base/android/log_utils.h"
+
namespace WeexCore {
bool MultiSoInitializer::Init(
@@ -66,4 +68,4 @@ bool MultiSoInitializer::Init(
}
return true;
}
-} // namespace WeexCore
\ No newline at end of file
+} // namespace WeexCore
diff --git a/weex_core/Source/android/bridge/platform/android_bridge.cpp b/weex_core/Source/android/bridge/platform/android_bridge.cpp
index 0236e80479..979cd0d08e 100644
--- a/weex_core/Source/android/bridge/platform/android_bridge.cpp
+++ b/weex_core/Source/android/bridge/platform/android_bridge.cpp
@@ -17,9 +17,10 @@
* under the License.
*/
-#include <base/LogDefines.h>
#include "android_bridge.h"
+
#include "android/bridge/platform/android_side.h"
+#include "base/log_defines.h"
#include "core/bridge/platform/core_side_in_platform.h"
namespace WeexCore {
@@ -33,4 +34,4 @@ AndroidBridgeInSimple::~AndroidBridgeInSimple() {
LOGE("~AndroidBridgeInSimple");
}
-} // namespace WeexCore
\ No newline at end of file
+} // namespace WeexCore
diff --git a/weex_core/Source/android/bridge/platform/android_bridge_in_multi_process.cc b/weex_core/Source/android/bridge/platform/android_bridge_in_multi_process.cc
index 6923bfbcad..9ccf0cd54e 100644
--- a/weex_core/Source/android/bridge/platform/android_bridge_in_multi_process.cc
+++ b/weex_core/Source/android/bridge/platform/android_bridge_in_multi_process.cc
@@ -18,21 +18,22 @@
*/
#include "android_bridge_in_multi_process.h"
-#include "IPC/IPCArguments.h"
-#include "IPC/IPCHandler.h"
-#include "IPC/IPCMessageJS.h"
-#include "IPC/IPCResult.h"
-#include "IPC/IPCSender.h"
-#include "IPC/Serializing/IPCSerializer.h"
+
#include "android/base/string/string_utils.h"
+#include "android/jsengine/bridge/script/core_side_in_multi_process.h"
#include "android/bridge/platform/android_side.h"
-#include "android/utils/IPCStringResult.h"
+#include "android/bridge/multi_process_and_so_initializer.h"
+#include "android/utils/ipc_string_result.h"
#include "core/layout/layout.h"
#include "core/manager/weex_core_manager.h"
#include "core/render/manager/render_manager.h"
-#include "core_side_in_multi_process.h"
#include "include/WeexApiHeader.h"
-#include "android/bridge/multi_process_and_so_initializer.h"
+#include "third_party/IPC/IPCArguments.h"
+#include "third_party/IPC/IPCHandler.h"
+#include "third_party/IPC/IPCMessageJS.h"
+#include "third_party/IPC/IPCResult.h"
+#include "third_party/IPC/IPCSender.h"
+#include "third_party/IPC/Serializing/IPCSerializer.h"
#include "wson/wson_parser.h"
namespace WeexCore {
@@ -832,4 +833,4 @@ std::unique_ptr<IPCResult> AndroidBridgeInMultiProcess::DispatchMessage(
return createVoidResult();
}
-} // namespace WeexCore
\ No newline at end of file
+} // namespace WeexCore
diff --git a/weex_core/Source/android/bridge/platform/android_bridge_in_multi_process.h b/weex_core/Source/android/bridge/platform/android_bridge_in_multi_process.h
index 8df6ed98d7..5670438aa4 100644
--- a/weex_core/Source/android/bridge/platform/android_bridge_in_multi_process.h
+++ b/weex_core/Source/android/bridge/platform/android_bridge_in_multi_process.h
@@ -20,9 +20,9 @@
#ifndef WEEX_PROJECT_IPC_BRIDGE_IMPL_H
#define WEEX_PROJECT_IPC_BRIDGE_IMPL_H
-#include "IPC/IPCHandler.h"
-#include "android/jsengine/multiprocess/WeexJSConnection.h"
+#include "android/multiprocess/weex_js_connection.h"
#include "core/bridge/platform_bridge.h"
+#include "third_party/IPC/IPCHandler.h"
class IPCArguments;
class IPCResult;
diff --git a/weex_core/Source/android/bridge/platform/android_side.cpp b/weex_core/Source/android/bridge/platform/android_side.cpp
index 8d55dbe994..e9b34514bb 100644
--- a/weex_core/Source/android/bridge/platform/android_side.cpp
+++ b/weex_core/Source/android/bridge/platform/android_side.cpp
@@ -18,12 +18,9 @@
*/
#include "android/bridge/platform/android_side.h"
-#include "IPC/IPCResult.h"
-#include "android/base/jni/android_jni.h"
-#include "android/base/jni/jbytearray_ref.h"
-#include "android/base/jni_type.h"
+
#include "android/base/string/string_utils.h"
-#include "android/utils/IPCStringResult.h"
+#include "android/utils/ipc_string_result.h"
#include "android/utils/cache_utils.h"
#include "android/utils/params_utils.h"
#include "android/wrap/hash_set.h"
@@ -31,10 +28,14 @@
#include "android/wrap/wml_bridge.h"
#include "android/wrap/wx_js_object.h"
#include "android/wrap/wx_map.h"
-#include "base/LogDefines.h"
+#include "base/android/jni/android_jni.h"
+#include "base/android/jni/jbytearray_ref.h"
+#include "base/android/jni_type.h"
+#include "base/log_defines.h"
#include "core/layout/layout.h"
#include "core/layout/measure_func_adapter.h"
#include "core/manager/weex_core_manager.h"
+#include "third_party/IPC/IPCResult.h"
namespace WeexCore {
@@ -73,26 +74,26 @@ void AndroidSide::InvokeLayoutAfter(const char *page_id, long render_ptr,
void AndroidSide::SetJSVersion(const char *version) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return;
- }
+
wx_bridge_->SetJSFrmVersion(env, version);
}
void AndroidSide::ReportException(const char *page_id, const char *func,
const char *exception_string) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return;
- }
+
wx_bridge_->ReportException(env, page_id, func, exception_string);
}
void AndroidSide::ReportServerCrash(const char *instance_id) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return;
- }
+
std::string crash_file;
crash_file.assign("/crash_dump.log");
wx_bridge_->ReportServerCrash(env, instance_id, crash_file.c_str());
@@ -101,18 +102,18 @@ void AndroidSide::ReportServerCrash(const char *instance_id) {
void AndroidSide::ReportNativeInitStatus(const char *status_code,
const char *error_msg) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return;
- }
+
wx_bridge_->ReportNativeInitStatus(env, status_code, error_msg);
}
int AndroidSide::CallNative(const char *page_id, const char *task,
const char *callback) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
int flag = wx_bridge_->CallNative(env, page_id, task, callback);
if (flag == -1) {
LOGE("instance destroy JFM must stop callNative");
@@ -126,14 +127,13 @@ std::unique_ptr<ValueWithType> AndroidSide::CallNativeModule(
int options_length) {
std::unique_ptr<ValueWithType> ipc_result(new ValueWithType());
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return ipc_result;
- }
+
auto result =
wx_bridge_->CallNativeModule(env, page_id, module, method, arguments,
arguments_length, options, options_length);
-
ipc_result->type = ParamsType::INT32;
ipc_result->value.int32Value = -1;
if (result.IsNull()) {
@@ -177,26 +177,26 @@ void AndroidSide::CallNativeComponent(const char *page_id, const char *ref,
int arguments_length, const char *options,
int options_length) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return;
- }
+
wx_bridge_->CallNativeComponent(env, page_id, ref, method, arguments,
arguments_length, options, options_length);
}
void AndroidSide::SetTimeout(const char *callback_id, const char *time) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return;
- }
+
wx_bridge_->SetTimeout(env, callback_id, time);
}
void AndroidSide::NativeLog(const char *str_array) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return;
- }
+
LogUtils::NativeLog(env, str_array);
}
@@ -204,9 +204,9 @@ int AndroidSide::UpdateFinish(const char *page_id, const char *task,
int taskLen, const char *callback,
int callbackLen) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
int flag = wx_bridge_->UpdateFinish(env, page_id, task, callback);
if (flag == -1) {
LOGE("instance destroy JFM must stop callUpdateFinish");
@@ -217,9 +217,9 @@ int AndroidSide::UpdateFinish(const char *page_id, const char *task,
int AndroidSide::RefreshFinish(const char *page_id, const char *task,
const char *callback) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
int flag = wx_bridge_->RefreshFinish(env, page_id, task, callback);
if (flag == -1) {
@@ -231,9 +231,9 @@ int AndroidSide::RefreshFinish(const char *page_id, const char *task,
int AndroidSide::AddEvent(const char *page_id, const char *ref,
const char *event) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
int flag = wx_bridge_->AddEvent(env, page_id, ref, event);
if (flag == -1) {
LOGE("instance destroy JFM must stop callAddEvent");
@@ -244,9 +244,9 @@ int AndroidSide::AddEvent(const char *page_id, const char *ref,
int AndroidSide::RemoveEvent(const char *page_id, const char *ref,
const char *event) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
int flag = wx_bridge_->RemoveEvent(env, page_id, ref, event);
if (flag == -1) {
LOGE("instance destroy JFM must stop callRemoveElement");
@@ -263,9 +263,9 @@ int AndroidSide::CreateBody(const char *page_id, const char *component_type,
const WXCorePadding &paddings,
const WXCoreBorderWidth &borders) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
int flag =
wx_bridge_->CreateBody(env, page_id, component_type, ref, styles,
attributes, events, margins, paddings, borders);
@@ -284,9 +284,9 @@ int AndroidSide::AddElement(const char *page_id, const char *component_type,
const WXCorePadding &paddings,
const WXCoreBorderWidth &borders, bool willLayout) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
int flag = wx_bridge_->AddElement(env, page_id, component_type, ref, index,
parentRef, styles, attributes, events,
margins, paddings, borders, willLayout);
@@ -301,12 +301,12 @@ int AndroidSide::Layout(const char *page_id, const char *ref, float top,
float bottom, float left, float right, float height,
float width, bool isRTL, int index) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
int flag = 0;
- wx_bridge_->Layout(env, page_id, ref, top, bottom, left, right, height, width, isRTL,
- index);
+ wx_bridge_->Layout(env, page_id, ref, top, bottom, left, right,
+ height, width, isRTL, index);
if (flag == -1) {
LOGE("instance destroy JFM must stop callLayout");
@@ -321,9 +321,9 @@ int AndroidSide::UpdateStyle(
std::vector<std::pair<std::string, std::string>> *padding,
std::vector<std::pair<std::string, std::string>> *border) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
int flag = wx_bridge_->UpdateStyle(env, page_id, ref, style, margin, padding,
border);
if (flag == -1) {
@@ -336,9 +336,9 @@ int AndroidSide::UpdateAttr(
const char *page_id, const char *ref,
std::vector<std::pair<std::string, std::string>> *attrs) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
int flag = 0;
flag = wx_bridge_->UpdateAttr(env, page_id, ref, attrs);
if (flag == -1) {
@@ -349,9 +349,9 @@ int AndroidSide::UpdateAttr(
int AndroidSide::CreateFinish(const char *page_id) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
int flag = wx_bridge_->CreateFinish(env, page_id);
if (flag == -1) {
@@ -362,9 +362,9 @@ int AndroidSide::CreateFinish(const char *page_id) {
int AndroidSide::RenderSuccess(const char *page_id) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
int flag = wx_bridge_->RenderSuccess(env, page_id);
if (flag == -1) {
@@ -375,6 +375,9 @@ int AndroidSide::RenderSuccess(const char *page_id) {
int AndroidSide::RemoveElement(const char *page_id, const char *ref) {
JNIEnv *env = base::android::AttachCurrentThread();
+ if (env == nullptr)
+ return -1;
+
int flag = wx_bridge_->RemoveElement(env, page_id, ref);
if (flag == -1) {
LOGE("instance destroy JFM must stop callRemoveElement");
@@ -385,9 +388,9 @@ int AndroidSide::RemoveElement(const char *page_id, const char *ref) {
int AndroidSide::MoveElement(const char *page_id, const char *ref,
const char *parent_ref, int index) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
int flag = wx_bridge_->MoveElement(env, page_id, ref, parent_ref, index);
if (flag == -1) {
LOGE("instance destroy JFM must stop callRemoveElement");
@@ -397,9 +400,6 @@ int AndroidSide::MoveElement(const char *page_id, const char *ref,
int AndroidSide::AppendTreeCreateFinish(const char *page_id, const char *ref) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
- return -1;
- }
int flag = wx_bridge_->AppendTreeCreateFinish(env, page_id, ref);
if (flag == -1) {
LOGE("instance destroy JFM must stop callAppendTreeCreateFinish");
@@ -411,9 +411,9 @@ int AndroidSide::HasTransitionPros(
const char *page_id, const char *ref,
std::vector<std::pair<std::string, std::string>> *style) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return -1;
- }
+
if (style == nullptr) {
return wx_bridge_->HasTransitionPros(env, page_id, ref, *style);
} else {
@@ -424,18 +424,18 @@ int AndroidSide::HasTransitionPros(
void AndroidSide::PostMessage(const char *vm_id, const char *data, int dataLength) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return;
- }
+
wml_bridge_->PostMessage(env, vm_id, data, dataLength);
}
void AndroidSide::DispatchMessage(const char *client_id,
const char *data, int dataLength, const char *callback, const char *vm_id) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return;
- }
+
wml_bridge_->DispatchMessage(env, client_id, data, dataLength, callback, vm_id);
}
@@ -443,6 +443,9 @@ std::unique_ptr<WeexJSResult> AndroidSide::DispatchMessageSync(
const char *client_id, const char *data, int dataLength,
const char *vm_id) {
JNIEnv *env = base::android::AttachCurrentThread();
+ if (env == nullptr)
+ return std::unique_ptr<WeexJSResult>();
+
auto jni_result =
wml_bridge_->DispatchMessageSync(env, client_id, data, dataLength, vm_id);
JByteArrayRef byte_array(env, jni_result.Get());
@@ -457,17 +460,17 @@ std::unique_ptr<WeexJSResult> AndroidSide::DispatchMessageSync(
void AndroidSide::OnReceivedResult(long callback_id, std::unique_ptr<WeexJSResult>& result) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return;
- }
+
wx_bridge_->OnReceivedResult(env, callback_id, result);
}
jobject AndroidSide::getMeasureFunc(const char *pageId, jlong renderObjectPtr) {
JNIEnv *env = base::android::AttachCurrentThread();
- if(env == nullptr) {
+ if (env == nullptr)
return nullptr;
- }
+
return wx_bridge_->GetMeasureFunc(env, pageId, renderObjectPtr).Release();
}
-} // namespace WeexCore
\ No newline at end of file
+} // namespace WeexCore
diff --git a/weex_core/Source/android/bridge/platform/android_side.h b/weex_core/Source/android/bridge/platform/android_side.h
index f9129920fd..1593e90965 100644
--- a/weex_core/Source/android/bridge/platform/android_side.h
+++ b/weex_core/Source/android/bridge/platform/android_side.h
@@ -80,7 +80,8 @@ class AndroidSide : public PlatformBridge::PlatformSide {
const WXCorePadding& paddings,
const WXCoreBorderWidth& borders, bool willLayout) override;
int Layout(const char* page_id, const char* ref, float top, float bottom,
- float left, float right, float height, float width, bool isRTL, int index) override;
+ float left, float right, float height, float width, bool isRTL,
+ int index) override;
int UpdateStyle(
const char* pageId, const char* ref,
diff --git a/weex_core/Source/android/bridge/platform/core_side_in_multi_process.cpp b/weex_core/Source/android/bridge/platform/core_side_in_multi_process.cpp
index dbd668ce44..ef0655daf1 100644
--- a/weex_core/Source/android/bridge/platform/core_side_in_multi_process.cpp
+++ b/weex_core/Source/android/bridge/platform/core_side_in_multi_process.cpp
@@ -16,17 +16,18 @@
* specific language governing permissions and limitations
* under the License.
*/
+#include "core_side_in_multi_process.h"
-#include "IPC/Serializing/IPCSerializer.h"
-#include "IPC/IPCMessageJS.h"
-#include "IPC/IPCSender.h"
-#include "IPC/IPCResult.h"
-#include "IPC/Buffering/IPCBuffer.h"
-#include "IPC/IPCException.h"
#include "android/base/log_utils.h"
+#include "android/utils/params_utils.h"
#include "core_side_in_multi_process.h"
-#include "../../../include/WeexApiHeader.h"
-#include "../../utils/params_utils.h"
+#include "include/WeexApiHeader.h"
+#include "third_party/IPC/Serializing/IPCSerializer.h"
+#include "third_party/IPC/IPCMessageJS.h"
+#include "third_party/IPC/IPCSender.h"
+#include "third_party/IPC/IPCResult.h"
+#include "third_party/IPC/Buffering/IPCBuffer.h"
+#include "third_party/IPC/IPCException.h"
namespace WeexCore {
@@ -571,7 +572,8 @@ namespace WeexCore {
int CoreSideInMultiProcess::CreateInstance(const char *instanceId, const char *func,
const char *script, const char *opts,
- const char *initData, const char *extendsApi, std::vector<INIT_FRAMEWORK_PARAMS*>& params,
+ const char *initData, const char *extendsApi,
+ std::vector<INIT_FRAMEWORK_PARAMS*>& params,
const char* render_strategy) {
try {
std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
@@ -586,6 +588,7 @@ namespace WeexCore {
serializer->add((*it)->type->content, (*it)->type->length);
serializer->add((*it)->value->content, (*it)->value->length);
}
+
std::unique_ptr<IPCBuffer> buffer = serializer->finish();
std::unique_ptr<IPCResult> result = sender_->send(buffer.get());
if (result->getType() != IPCType::INT32) {
@@ -667,4 +670,4 @@ namespace WeexCore {
}
return true;
}
-}
\ No newline at end of file
+}
diff --git a/weex_core/Source/android/bridge/platform/core_side_in_multi_so.cpp b/weex_core/Source/android/bridge/platform/core_side_in_multi_so.cpp
index a627a93563..0cff3382ff 100644
--- a/weex_core/Source/android/bridge/platform/core_side_in_multi_so.cpp
+++ b/weex_core/Source/android/bridge/platform/core_side_in_multi_so.cpp
@@ -207,7 +207,7 @@ int CoreSideInMultiSo::CreateInstance(const char *instanceId, const char *func,
const char *initData,
const char *extendsApi, std::vector<INIT_FRAMEWORK_PARAMS*>& params, const char* render_strategy) {
return core_side_functions_->create_instance(instanceId, func, script, opts,
- initData, extendsApi,params);
+ initData, extendsApi, params);
}
std::unique_ptr<WeexJSResult> CoreSideInMultiSo::ExecJSOnInstance(const char *instanceId,
@@ -222,4 +222,4 @@ int CoreSideInMultiSo::DestroyInstance(const char *instanceId) {
int CoreSideInMultiSo::UpdateGlobalConfig(const char *config) {
return core_side_functions_->update_global_config(config);
}
-} // namespace WeexCore
\ No newline at end of file
+} // namespace WeexCore
diff --git a/weex_core/Source/android/bridge/script/script_side_in_multi_process.cpp b/weex_core/Source/android/bridge/script/script_side_in_multi_process.cpp
index 9217f78640..df0570045d 100644
--- a/weex_core/Source/android/bridge/script/script_side_in_multi_process.cpp
+++ b/weex_core/Source/android/bridge/script/script_side_in_multi_process.cpp
@@ -19,14 +19,15 @@
#include <android/utils/params_utils.h>
#include "script_side_in_multi_process.h"
-#include "IPC/Buffering/IPCBuffer.h"
-#include "IPC/IPCException.h"
-#include "IPC/IPCMessageJS.h"
-#include "IPC/IPCSender.h"
-#include "IPC/Serializing/IPCSerializer.h"
-#include "android/base/log_utils.h"
+
#include "android/bridge/multi_process_and_so_initializer.h"
+#include "base/android/log_utils.h"
#include "core/manager/weex_core_manager.h"
+#include "third_party/IPC/Buffering/IPCBuffer.h"
+#include "third_party/IPC/IPCException.h"
+#include "third_party/IPC/IPCMessageJS.h"
+#include "third_party/IPC/IPCSender.h"
+#include "third_party/IPC/Serializing/IPCSerializer.h"
namespace WeexCore {
namespace bridge {
@@ -42,8 +43,6 @@ int ScriptSideInMultiProcess::InitFramework(
LOGE("InitFramework sender is null");
return false;
}
-
-
std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::INITFRAMEWORK));
serializer->add(script, strlen(script));
@@ -453,6 +452,7 @@ int ScriptSideInMultiProcess::CreateInstance(
serializer->add((*it)->type->content, (*it)->type->length);
serializer->add((*it)->value->content, (*it)->value->length);
}
+
std::unique_ptr<IPCBuffer> buffer = serializer->finish();
std::unique_ptr<IPCResult> result = sender_->send(buffer.get());
if (result->getType() != IPCType::INT32) {
@@ -553,4 +553,4 @@ int ScriptSideInMultiProcess::UpdateGlobalConfig(const char *config) {
}
} // namespace script
} // namespace bridge
-} // namespace WeexCore
\ No newline at end of file
+} // namespace WeexCore
diff --git a/weex_core/Source/android/bridge/script/script_side_in_multi_so.cpp b/weex_core/Source/android/bridge/script/script_side_in_multi_so.cpp
index c43ea28f03..2072c80962 100644
--- a/weex_core/Source/android/bridge/script/script_side_in_multi_so.cpp
+++ b/weex_core/Source/android/bridge/script/script_side_in_multi_so.cpp
@@ -18,7 +18,7 @@
*/
#include "script_side_in_multi_so.h"
-#include <android/base/log_utils.h>
+#include "base/android/log_utils.h"
namespace WeexCore {
namespace bridge {
@@ -146,7 +146,7 @@ int ScriptSideInMultiSo::CreateInstance(const char *instanceId,
return false;
}
return script_side_functions_->funcCreateInstance(instanceId, func, script,
- opts, initData, extendsApi,params);
+ opts, initData, extendsApi, params);
}
std::unique_ptr<WeexJSResult> ScriptSideInMultiSo::ExecJSOnInstance(const char *instanceId,
@@ -176,4 +176,4 @@ int ScriptSideInMultiSo::UpdateGlobalConfig(const char *config) {
}
} // namespace script
} // namespace bridge
-} // namespace WeexCore
\ No newline at end of file
+} // namespace WeexCore
diff --git a/weex_core/Source/android/bridge/script_bridge_in_multi_process.cpp b/weex_core/Source/android/bridge/script_bridge_in_multi_process.cpp
index 9a5e4eb634..29deee1527 100644
--- a/weex_core/Source/android/bridge/script_bridge_in_multi_process.cpp
+++ b/weex_core/Source/android/bridge/script_bridge_in_multi_process.cpp
@@ -17,23 +17,24 @@
* under the License.
*/
#include "script_bridge_in_multi_process.h"
-#include <android/utils/params_utils.h>
-#include <base/make_copyable.h>
-#include <base/message_loop/message_loop.h>
-#include <base/thread/waitable_event.h>
-#include "IPC/IPCArguments.h"
-#include "IPC/IPCHandler.h"
-#include "IPC/IPCMessageJS.h"
-#include "IPC/IPCResult.h"
-#include "android/base/jni/android_jni.h"
-#include "android/base/log_utils.h"
+
+#include "android/utils/params_utils.h"
#include "android/base/string/string_utils.h"
#include "android/bridge/multi_process_and_so_initializer.h"
#include "android/bridge/script/script_side_in_multi_process.h"
-#include "android/jsengine/multiprocess/WeexJSConnection.h"
-#include "android/utils/IPCStringResult.h"
+#include "android/multiprocess/weex_js_connection.h"
+#include "android/utils/ipc_string_result.h"
+#include "base/android/log_utils.h"
+#include "base/make_copyable.h"
+#include "base/message_loop/message_loop.h"
+#include "base/thread/waitable_event.h"
+#include "base/android/jni/android_jni.h"
#include "core/bridge/script/core_side_in_script.h"
#include "core/manager/weex_core_manager.h"
+#include "third_party/IPC/IPCArguments.h"
+#include "third_party/IPC/IPCHandler.h"
+#include "third_party/IPC/IPCMessageJS.h"
+#include "third_party/IPC/IPCResult.h"
namespace WeexCore {
@@ -70,6 +71,8 @@ static std::unique_ptr<IPCResult> HandleReportException(
}
LOGE(" ReportException : %s", exceptionInfo);
+ WeexCoreManager::Instance()->script_bridge()->core_side()->ReportException(
+ pageId, func, exceptionInfo);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([pageId = std::string(pageId),
@@ -986,7 +989,7 @@ ScriptBridgeInMultiProcess::ScriptBridgeInMultiProcess() {
connection_ = std::move(connection);
handler_ = std::move(handler);
server_handler_ = std::move(server_handler);
- LOGE("ScriptBridgeInMultiProcess finish %x %x", server_handler_.get(),
+ LOGE("ScriptBridgeInMultiProcess finish %p %p", server_handler_.get(),
server_handler.get());
return true;
},
@@ -1005,10 +1008,8 @@ ScriptBridgeInMultiProcess::~ScriptBridgeInMultiProcess() {
}
void ScriptBridgeInMultiProcess::RegisterIPCCallback(IPCHandler *handler) {
- LOGE("RegisterIPCCallback is running");
handler->registerHandler(static_cast<uint32_t>(IPCProxyMsg::SETJSFVERSION),
HandleSetJSVersion);
- LOGE("RegisterIPCCallback is running2");
handler->registerHandler(static_cast<uint32_t>(IPCProxyMsg::REPORTEXCEPTION),
HandleReportException);
handler->registerHandler(static_cast<uint32_t>(IPCProxyMsg::CALLNATIVE),
diff --git a/weex_core/Source/android/bridge/script_bridge_in_multi_so.cpp b/weex_core/Source/android/bridge/script_bridge_in_multi_so.cpp
index 32f06e5efb..706686fa8d 100644
--- a/weex_core/Source/android/bridge/script_bridge_in_multi_so.cpp
+++ b/weex_core/Source/android/bridge/script_bridge_in_multi_so.cpp
@@ -18,15 +18,16 @@
*/
#include "script_bridge_in_multi_so.h"
-#include <base/thread/waitable_event.h>
#include <dlfcn.h>
#include <malloc.h>
-#include "android/base/log_utils.h"
+
#include "android/bridge/multi_so_initializer.h"
#include "android/bridge/script/script_side_in_multi_so.h"
-#include "android/utils/IPCStringResult.h"
+#include "android/utils/ipc_string_result.h"
#include "android/utils/params_utils.h"
+#include "base/android/log_utils.h"
#include "base/make_copyable.h"
+#include "base/thread/waitable_event.h"
#include "core/bridge/script/core_side_in_script.h"
#include "core/manager/weex_core_manager.h"
diff --git a/weex_core/Source/android/jsengine/CMakeLists.txt b/weex_core/Source/android/jsengine/CMakeLists.txt
new file mode 100644
index 0000000000..b914ed271a
--- /dev/null
+++ b/weex_core/Source/android/jsengine/CMakeLists.txt
@@ -0,0 +1,183 @@
+#cmake_minimum_required(VERSION 3.3)
+#if (POLICY CMP0042)
+# cmake_policy(SET CMP0042 NEW)
+#endif ()
+
+set(PORT JSCOnly)
+add_definitions(-DPRINT_LOG_CACHEFILE=0)
+add_definitions(-DOS_ANDROID)
+
+add_definitions(-DUSE_SYSTEM_MALLOC=1)
+if (${ANDROID_PLATFORM} STREQUAL "android-21")
+else ()
+ add_definitions(-D_POSIX_THREAD_KEYS_MAX=128)
+ add_definitions(-DPTHREAD_KEYS_MAX=_POSIX_THREAD_KEYS_MAX)
+endif ()
+
+if ("${ANDROID_ABI}" STREQUAL "armeabi")
+ add_definitions(-DWTF_CPU_ARM)
+ set(WTF_CPU_ARM 1)
+
+ if ("${ANDROID_TOOLCHAIN}" STREQUAL clang)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a")
+ endif ()
+elseif ("${ANDROID_ABI}" STREQUAL "armeabi-v7a")
+ add_definitions(-DWTF_CPU_ARM)
+ set(WTF_CPU_ARM 1)
+else ()
+ add_definitions(-DWTF_CPU_X86)
+ set(WTF_CPU_X86_64 1)
+endif ()
+
+set(USE_SYSTEM_MALLOC 1)
+set(WEEXJSSERVER_NAME weexjss)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+include_directories(${WEEX_CORE_SOURCE_DIR})
+include_directories(${WEEX_CORE_SOURCE_DIR}/include)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/API)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/ForwardingHeaders)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/assembler)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/bytecode)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/dfg)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/disassembler)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/domjit)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/runtime)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/heap)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/jit)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/interpreter)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/parser)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/profiler)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/JavaScriptCore/yarr)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/wtf/icu)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/wtf/text)
+include_directories(${WEEX_CORE_SOURCE_DIR}/include/wtf)
+#include_directories(${WEEX_CORE_SOURCE_DIR}/android/jsengine/dependence/WTF/)
+#include_directories(${WEEX_CORE_SOURCE_DIR}/android/jsengine/dependence/icu)
+
+set(${WEEXJSSERVER_NAME}_SOURCES
+ weex_ipc_client.h
+ weex_ipc_client.cpp
+ weex_ipc_server.h
+ weex_ipc_server.cpp
+ weex_jsc_utils.h
+ weex_jsc_utils.cpp
+ weex_runtime.h
+ weex_runtime.cpp
+
+ bridge/script/script_bridge_in_multi_so.cpp
+ bridge/script/script_bridge_in_multi_process.cpp
+ bridge/script/core_side_in_multi_so.cpp
+ bridge/script/core_side_in_multi_process.cpp
+ bridge/script/script_side_in_simple.cpp
+ bridge/script/script_side_in_queue.cpp
+
+ object/args/exe_js_args.cpp
+ object/args/init_framework_args.cpp
+ object/args.h
+ object/args.cpp
+ object/weex_console_object.h
+ object/weex_console_object.cpp
+ object/weex_env.h
+ object/weex_env.cpp
+ object/weex_global_object.h
+ object/weex_global_object.cpp
+ object/weex_object_holder.h
+ object/weex_object_holder.cpp
+ object/weex_simple_object.h
+ object/weex_simple_object.cpp
+
+ task/impl/init_framework_task.cpp
+ task/impl/create_app_context_task.cpp
+ task/impl/create_instance_task.cpp
+ task/impl/call_js_on_app_context_task.cpp
+ task/impl/destory_app_context_task.cpp
+ task/impl/destory_instance_task.cpp
+ task/impl/exe_js_on_app_with_result.cpp
+ task/impl/update_global_config_task.cpp
+ task/impl/ctime_callback_task.cpp
+ task/impl/exe_js_services_task.cpp
+ task/impl/exe_js_on_instance_task.cpp
+ task/impl/exe_js_task.cpp
+ task/impl/take_heap_snapshot.cpp
+ task/impl/native_timer_task.cpp
+ task/weex_task.cpp
+ task/weex_task_queue.cpp
+ task/timer_task.cpp
+ task/timer_queue.cpp
+
+ wson/wson_jsc.h
+ wson/wson_jsc.cpp
+)
+link_directories(${LOCAL_LIBRARIES_DIR})
+SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}" CACHE STRING "toolchain_exelinkflags" FORCE)
+SET(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS} -shared")
+
+#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -fno-omit-frame-pointer")# -fsanitize=address -g3")
+set(WEEXJSSERVERSTUB_NAME libweexjsb.so)
+add_executable(${WEEXJSSERVERSTUB_NAME}
+ weex_js_server_main_stub.cpp)
+
+set_target_properties(${WEEXJSSERVERSTUB_NAME}
+PROPERTIES
+LINK_FLAGS
+"-pie -fPIE"
+)
+
+target_link_libraries(${WEEXJSSERVERSTUB_NAME}
+${WEEXJSSERVER_NAME}
+)
+
+if (APPLE)
+set_target_properties(${WEEXJSSERVERSTUB_NAME}
+PROPERTIES LINK_FLAGS
+"-Wl,--entry=_start"
+)
+endif()
+
+
+set(${WEEXJSSERVER_NAME}_LIBRARY_TYPE SHARED)
+
+set(${WEEXJSSERVER_NAME}_LIBRARIES
+weexbase
+weexipc
+wson
+JavaScriptCore
+WTF
+log
+z
+-lc
+-ldl
+-pthread
+)
+
+add_library(${WEEXJSSERVER_NAME} SHARED
+ ${${WEEXJSSERVER_NAME}_SOURCES})
+
+
+target_link_libraries(${WEEXJSSERVER_NAME}
+ ${${WEEXJSSERVER_NAME}_LIBRARIES})
+set_target_properties(${WEEXJSSERVER_NAME} PROPERTIES NO_SONAME TRUE)
+
+set_target_properties(${WEEXJSSERVER_NAME}
+PROPERTIES
+LINK_FLAGS
+"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}//weexjsserver_version_script.txt -Wl,--no-undefined -Wl,-soname,libweexjss${SERVERSUFFIX}.so"
+)
+
+#add_custom_command(
+# TARGET ${WEEXJSSERVER_NAME}
+# POST_BUILD
+# COMMAND cp $<TARGET_FILE:${WEEXJSSERVER_NAME}> ${CMAKE_SOURCE_DIR}/libweexjss${SERVERSUFFIX}.so
+# VERBATIM
+#)
+
+#add_custom_command(
+# TARGET ${WEEXJSSERVERSTUB_NAME}
+# POST_BUILD
+# COMMAND cp $<TARGET_FILE:${WEEXJSSERVERSTUB_NAME}> ${CMAKE_SOURCE_DIR}/libweexjsb${SERVERSUFFIX}.so
+# VERBATIM
+#)
diff --git a/weex_core/Source/android/jsengine/bridge/platform/core_side_in_simple.cpp b/weex_core/Source/android/jsengine/bridge/platform/core_side_in_simple.cpp
new file mode 100644
index 0000000000..c309a53efa
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/platform/core_side_in_simple.cpp
@@ -0,0 +1,416 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/14.
+//
+
+#include "core_side_in_simple.h"
+
+#include "android/jsengine/bridge/script/script_bridge_in_simple.h"
+#include "android/base/log_utils.h"
+#include "core/config/core_environment.h"
+#include "core/manager/weex_core_manager.h"
+#include "core/render/manager/render_manager.h"
+#include "core/render/node/factory/render_creator.h"
+#include "core/render/node/factory/render_type.h"
+#include "core/render/node/render_list.h"
+#include "core/render/node/render_object.h"
+#include "core/render/page/render_page.h"
+
+using namespace WeexCore;
+namespace weex {
+void CoreSideInSimple::SetDefaultHeightAndWidthIntoRootDom(
+ const std::string &instance_id, float default_width, float default_height,
+ bool is_width_wrap_content, bool is_height_wrap_content) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page == nullptr) return;
+
+#if RENDER_LOG
+ LOGD(
+ "[JNI] SetDefaultHeightAndWidthIntoRootDom >>>> pageId: %s, "
+ "defaultWidth: %f, defaultHeight: %f",
+ page->PageId().c_str(), defaultWidth, defaultHeight);
+#endif
+
+ page->SetDefaultHeightAndWidthIntoRootRender(default_width, default_height,
+ is_width_wrap_content,
+ is_height_wrap_content);
+}
+
+void CoreSideInSimple::OnInstanceClose(const std::string &instance_id) {
+ RenderManager::GetInstance()->ClosePage(instance_id);
+}
+
+void CoreSideInSimple::SetStyleWidth(const std::string &instance_id,
+ const std::string &render_ref,
+ float width) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page == nullptr) return;
+
+ RenderObject *render = page->GetRenderObject(render_ref);
+ if (render == nullptr) return;
+
+ render->setStyleWidthLevel(CSS_STYLE);
+ render->setStyleWidth(width, true);
+ page->set_is_dirty(true);
+}
+
+void CoreSideInSimple::SetStyleHeight(const std::string &instance_id,
+ const std::string &render_ref,
+ float height) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page == nullptr) return;
+
+ RenderObject *render = page->GetRenderObject(render_ref);
+ if (render == nullptr) return;
+
+ render->setStyleHeightLevel(CSS_STYLE);
+ render->setStyleHeight(height);
+ page->set_is_dirty(true);
+}
+
+void CoreSideInSimple::SetMargin(const std::string &instance_id,
+ const std::string &render_ref, int edge,
+ float value) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page == nullptr) return;
+
+ RenderObject *render = page->GetRenderObject(render_ref);
+ if (render == nullptr) return;
+
+ if (edge == 0) {
+ render->setMargin(kMarginTop, value);
+ } else if (edge == 1) {
+ render->setMargin(kMarginBottom, value);
+ } else if (edge == 2) {
+ render->setMargin(kMarginLeft, value);
+ } else if (edge == 3) {
+ render->setMargin(kMarginRight, value);
+ } else if (edge == 4) {
+ render->setMargin(kMarginALL, value);
+ }
+ page->set_is_dirty(true);
+}
+void CoreSideInSimple::SetPadding(const std::string &instance_id,
+ const std::string &render_ref, int edge,
+ float value) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page == nullptr) return;
+
+ RenderObject *render = page->GetRenderObject(render_ref);
+ if (render == nullptr) return;
+
+ if (edge == 0) {
+ render->setPadding(kPaddingTop, value);
+ } else if (edge == 1) {
+ render->setPadding(kPaddingBottom, value);
+ } else if (edge == 2) {
+ render->setPadding(kPaddingLeft, value);
+ } else if (edge == 3) {
+ render->setPadding(kPaddingRight, value);
+ } else if (edge == 4) {
+ render->setPadding(kPaddingALL, value);
+ }
+ page->set_is_dirty(true);
+}
+
+void CoreSideInSimple::SetPosition(const std::string &instance_id,
+ const std::string &render_ref, int edge,
+ float value) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page == nullptr) return;
+
+ RenderObject *render = page->GetRenderObject(render_ref);
+ if (render == nullptr) return;
+
+ if (edge == 0) {
+ render->setStylePosition(kPositionEdgeTop, value);
+ } else if (edge == 1) {
+ render->setStylePosition(kPositionEdgeBottom, value);
+ } else if (edge == 2) {
+ render->setStylePosition(kPositionEdgeLeft, value);
+ } else if (edge == 3) {
+ render->setStylePosition(kPositionEdgeRight, value);
+ }
+ page->set_is_dirty(true);
+}
+
+void CoreSideInSimple::MarkDirty(const std::string &instance_id,
+ const std::string &render_ref) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page == nullptr) return;
+
+ RenderObject *render = page->GetRenderObject(render_ref);
+ if (render == nullptr) return;
+ render->markDirty();
+}
+
+void CoreSideInSimple::SetViewPortWidth(const std::string &instance_id,
+ float width) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page == nullptr) return;
+
+ page->set_viewport_width(width);
+}
+
+void CoreSideInSimple::ForceLayout(const std::string &instance_id) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page != nullptr) {
+#if RENDER_LOG
+ LOGD("[JNI] ForceLayout >>>> pageId: %s, needForceLayout: %s",
+ jString2StrFast(env, instanceId).c_str(),
+ page->hasForeLayoutAction.load() ? "true" : "false");
+#endif
+
+ page->LayoutImmediately();
+ page->has_fore_layout_action_.store(false);
+ }
+}
+
+bool CoreSideInSimple::NotifyLayout(const std::string &instance_id) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page != nullptr) {
+ if (!page->need_layout_.load()) {
+ page->need_layout_.store(true);
+ }
+
+ bool ret = !page->has_fore_layout_action_.load() && page->is_dirty();
+ if (ret) {
+ page->has_fore_layout_action_.store(true);
+ }
+ return ret ? true : false;
+ }
+ return false;
+}
+std::vector<int64_t> CoreSideInSimple::GetFirstScreenRenderTime(
+ const std::string &instance_id) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page == nullptr) {
+ return std::vector<int64_t>();
+ } else {
+ return page->PrintFirstScreenLog();
+ }
+}
+std::vector<int64_t> CoreSideInSimple::GetRenderFinishTime(
+ const std::string &instance_id) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page == nullptr) {
+ return std::vector<int64_t>();
+ } else {
+ return page->PrintRenderSuccessLog();
+ }
+}
+void CoreSideInSimple::SetRenderContainerWrapContent(
+ const std::string &instance_id, bool wrap) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page == nullptr) return;
+
+ page->set_is_render_container_width_wrap_content(wrap);
+}
+
+void CoreSideInSimple::BindMeasurementToRenderObject(long ptr) {
+ RenderObject *render = convert_long_to_render_object(ptr);
+ if (render && measure_function_adapter_exist_) {
+ render->BindMeasureFunc();
+ }
+}
+
+void CoreSideInSimple::RegisterCoreEnv(const std::string &key,
+ const std::string &value) {
+ WXCoreEnvironment::getInstance()->AddOption(key, value);
+}
+
+long CoreSideInSimple::GetRenderObject(const std::string &instance_id,
+ const std::string &render_ref) {
+ RenderPage *page = RenderManager::GetInstance()->GetPage(instance_id);
+ if (page == nullptr) {
+ return 0;
+ }
+
+ RenderObject *render = page->GetRenderObject(render_ref);
+ if (render == nullptr) {
+ return 0;
+ }
+ return convert_render_object_to_long(render);
+}
+void CoreSideInSimple::UpdateRenderObjectStyle(long render_ptr,
+ const std::string &key,
+ const std::string &value) {
+ RenderObject *render = convert_long_to_render_object(render_ptr);
+ render->UpdateStyle(key, value);
+}
+
+void CoreSideInSimple::UpdateRenderObjectAttr(long render_ptr,
+ const std::string &key,
+ const std::string &value) {
+ RenderObject *render = convert_long_to_render_object(render_ptr);
+ render->UpdateAttr(key, value);
+ render->markDirty(true);
+}
+
+long CoreSideInSimple::CopyRenderObject(long render_ptr) {
+ RenderObject *render = convert_long_to_render_object(render_ptr);
+ RenderObject *copy =
+ static_cast<RenderObject *>(RenderCreator::GetInstance()->CreateRender(
+ render->type(), render->ref()));
+ copy->copyFrom(render);
+ if (render->type() == WeexCore::kRenderCellSlot ||
+ render->type() == WeexCore::kRenderCell) {
+ RenderList *renderList = static_cast<RenderList *>(render->getParent());
+ if (renderList != nullptr) {
+ renderList->AddCellSlotCopyTrack(copy);
+ } else {
+ LOGE("LayoutRenderObject", "copy error parent null");
+ }
+ }
+ return convert_render_object_to_long(copy);
+}
+
+void CoreSideInSimple::SetMeasureFunctionAdapter() {
+ measure_function_adapter_exist_ = true;
+}
+
+void CoreSideInSimple::SetPlatform(const std::string &platformName) {
+ WXCoreEnvironment::getInstance()->SetPlatform(platformName);
+}
+
+void CoreSideInSimple::SetDeviceWidthAndHeight(float width, float height) {
+ WXCoreEnvironment::getInstance()->set_device_width(width);
+ WXCoreEnvironment::getInstance()->set_device_height(height);
+}
+
+void CoreSideInSimple::AddOption(const std::string &key,
+ const std::string &value) {
+ WXCoreEnvironment::getInstance()->AddOption(key, value);
+}
+
+int CoreSideInSimple::InitFramework(
+ const char *script, std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) {
+ WeexCoreManager::Instance()->set_script_bridge(
+ weex::bridge::js::ScriptBridgeInSimple::Instance());
+ return WeexCoreManager::Instance()
+ ->script_bridge()
+ ->script_side()
+ ->InitFramework(script, params);
+}
+
+int CoreSideInSimple::InitAppFramework(
+ const char *instanceId, const char *appFramework,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) {
+ return WeexCoreManager::Instance()
+ ->script_bridge()
+ ->script_side()
+ ->InitAppFramework(instanceId, appFramework, params);
+}
+
+int CoreSideInSimple::CreateAppContext(const char *instanceId,
+ const char *jsBundle) {
+ return WeexCoreManager::Instance()
+ ->script_bridge()
+ ->script_side()
+ ->CreateAppContext(instanceId, jsBundle);
+}
+
+std::unique_ptr<WeexJSResult> CoreSideInSimple::ExecJSOnAppWithResult(const char *instanceId,
+ const char *jsBundle) {
+ return WeexCoreManager::Instance()
+ ->script_bridge()
+ ->script_side()
+ ->ExecJSOnAppWithResult(instanceId, jsBundle);
+}
+
+int CoreSideInSimple::CallJSOnAppContext(
+ const char *instanceId, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ return WeexCoreManager::Instance()
+ ->script_bridge()
+ ->script_side()
+ ->CallJSOnAppContext(instanceId, func, params);
+}
+
+int CoreSideInSimple::DestroyAppContext(const char *instanceId) {
+ return WeexCoreManager::Instance()
+ ->script_bridge()
+ ->script_side()
+ ->DestroyAppContext(instanceId);
+}
+
+int CoreSideInSimple::ExecJsService(const char *source) {
+ return WeexCoreManager::Instance()
+ ->script_bridge()
+ ->script_side()
+ ->ExecJsService(source);
+}
+
+int CoreSideInSimple::ExecTimeCallback(const char *source) {
+ return WeexCoreManager::Instance()
+ ->script_bridge()
+ ->script_side()
+ ->ExecTimeCallback(source);
+}
+
+int CoreSideInSimple::ExecJS(const char *instanceId, const char *nameSpace,
+ const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ return WeexCoreManager::Instance()->script_bridge()->script_side()->ExecJS(
+ instanceId, nameSpace, func, params);
+}
+
+WeexJSResult CoreSideInSimple::ExecJSWithResult(
+ const char *instanceId, const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ return WeexCoreManager::Instance()
+ ->script_bridge()
+ ->script_side()
+ ->ExecJSWithResult(instanceId, nameSpace, func, params);
+}
+
+int CoreSideInSimple::CreateInstance(const char *instanceId, const char *func,
+ const char *script, const char *opts,
+ const char *initData,
+ const char *extendsApi,
+ std::vector<INIT_FRAMEWORK_PARAMS*>& params) {
+ return WeexCoreManager::Instance()
+ ->script_bridge()
+ ->script_side()
+ ->CreateInstance(instanceId, func, script, opts, initData, extendsApi,params);
+}
+
+const char *CoreSideInSimple::ExecJSOnInstance(const char *instanceId,
+ const char *script) {
+ return WeexCoreManager::Instance()
+ ->script_bridge()
+ ->script_side()
+ ->ExecJSOnInstance(instanceId, script);
+}
+
+int CoreSideInSimple::DestroyInstance(const char *instanceId) {
+ return WeexCoreManager::Instance()
+ ->script_bridge()
+ ->script_side()
+ ->DestroyInstance(instanceId);
+}
+
+int CoreSideInSimple::UpdateGlobalConfig(const char *config) {
+ return WeexCoreManager::Instance()
+ ->script_bridge()
+ ->script_side()
+ ->UpdateGlobalConfig(config);
+}
+} // namespace weex
diff --git a/weex_core/Source/android/jsengine/bridge/platform/core_side_in_simple.h b/weex_core/Source/android/jsengine/bridge/platform/core_side_in_simple.h
new file mode 100644
index 0000000000..26cfabcfc6
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/platform/core_side_in_simple.h
@@ -0,0 +1,106 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/14.
+//
+
+#ifndef WEEXV8_SIMPLECORESIDE_H
+#define WEEXV8_SIMPLECORESIDE_H
+
+#include "base/common.h"
+#include "core/bridge/platform_bridge.h"
+
+namespace weex {
+class CoreSideInSimple : public WeexCore::PlatformBridge::CoreSide {
+ public:
+ CoreSideInSimple() {}
+ virtual ~CoreSideInSimple() {}
+ void SetDefaultHeightAndWidthIntoRootDom(
+ const std::string& instance_id, float default_width, float default_height,
+ bool is_width_wrap_content, bool is_height_wrap_content) override;
+ void OnInstanceClose(const std::string& instance_id) override;
+ void SetStyleWidth(const std::string& instance_id,
+ const std::string& render_ref, float width) override;
+ void SetStyleHeight(const std::string& instance_id,
+ const std::string& render_ref, float height) override;
+ void SetMargin(const std::string& instance_id, const std::string& render_ref,
+ int edge, float value) override;
+ void SetPadding(const std::string& instance_id, const std::string& render_ref,
+ int edge, float value) override;
+ void SetPosition(const std::string& instance_id,
+ const std::string& render_ref, int edge,
+ float value) override;
+ void MarkDirty(const std::string& instance_id,
+ const std::string& render_ref) override;
+ void SetViewPortWidth(const std::string& instance_id, float width) override;
+ void ForceLayout(const std::string& instance_id) override;
+ bool NotifyLayout(const std::string& instance_id) override;
+ std::vector<int64_t> GetFirstScreenRenderTime(
+ const std::string& instance_id) override;
+ std::vector<int64_t> GetRenderFinishTime(
+ const std::string& instance_id) override;
+ void SetRenderContainerWrapContent(const std::string& instance_id,
+ bool wrap) override;
+ void BindMeasurementToRenderObject(long ptr) override;
+ void RegisterCoreEnv(const std::string& key,
+ const std::string& value) override;
+
+ long GetRenderObject(const std::string& instance_id,
+ const std::string& render_ref) override;
+ void UpdateRenderObjectStyle(long render_ptr, const std::string& key,
+ const std::string& value) override;
+ void UpdateRenderObjectAttr(long render_ptr, const std::string& key,
+ const std::string& value) override;
+ long CopyRenderObject(long render_ptr) override;
+ void SetMeasureFunctionAdapter() override;
+ void SetPlatform(const std::string& platformName) override;
+ void SetDeviceWidthAndHeight(float width, float height) override;
+ void AddOption(const std::string& key, const std::string& value) override;
+
+ int InitFramework(const char *script,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) override;
+ int InitAppFramework(const char *instanceId, const char *appFramework,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) override;
+ int CreateAppContext(const char *instanceId, const char *jsBundle) override;
+ std::unique_ptr<WeexJSResult> ExecJSOnAppWithResult(const char *instanceId,
+ const char *jsBundle) override;
+ int CallJSOnAppContext(const char *instanceId, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶m) override;
+ int DestroyAppContext(const char *instanceId) override;
+ int ExecJsService(const char *source) override;
+ int ExecTimeCallback(const char *source) override;
+ int ExecJS(const char *instanceId, const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶m) override;
+ WeexJSResult ExecJSWithResult(const char *instanceId, const char *nameSpace,
+ const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶m) override;
+ int CreateInstance(const char *instanceId, const char *func,
+ const char *script, const char *opts, const char *initData,
+ const char *extendsApi,
+ std::vector<INIT_FRAMEWORK_PARAMS*>& params) override;
+ const char *ExecJSOnInstance(const char *instanceId, const char *script) override;
+ int DestroyInstance(const char *instanceId) override;
+ int UpdateGlobalConfig(const char *config) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CoreSideInSimple);
+};
+} // namespace weex
+
+#endif // WEEXV8_SIMPLECORESIDE_H
diff --git a/weex_core/Source/android/jsengine/bridge/platform/platform_bridge_in_multi_process.cpp b/weex_core/Source/android/jsengine/bridge/platform/platform_bridge_in_multi_process.cpp
new file mode 100644
index 0000000000..ebb3b42915
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/platform/platform_bridge_in_multi_process.cpp
@@ -0,0 +1,749 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/12.
+//
+
+#include "platform_bridge_in_multi_process.h"
+#include <cstring>
+#include "android/jsengine/bridge/platform/core_side_in_simple.h"
+#include "android/jsengine/bridge/platform/platform_side_multi_process.h"
+#include "android/jsengine/bridge/script/script_bridge_in_simple.h"
+#include "android/jsengine/utils/Utils.h"
+#include "base/android/log_utils.h"
+#include "core/config/core_environment.h"
+#include "core/manager/weex_core_manager.h"
+#include "third_party/IPC/IPCArguments.h"
+#include "third_party/IPC/IPCByteArray.h"
+#include "third_party/IPC/IPCHandler.h"
+#include "third_party/IPC/IPCMessageJS.h"
+#include "third_party/IPC/IPCResult.h"
+
+namespace weex {
+PlatformBridgeInMultiProcess* PlatformBridgeInMultiProcess::g_instance = NULL;
+
+PlatformBridgeInMultiProcess::PlatformBridgeInMultiProcess() {
+ set_core_side(new CoreSideInSimple);
+ set_platform_side(new PlatformSideInMultiProcess);
+}
+
+PlatformBridgeInMultiProcess::~PlatformBridgeInMultiProcess() {}
+
+void PlatformBridgeInMultiProcess::RegisterIPCCallback(IPCHandler* handler) {
+ handler->registerHandler(
+ static_cast<uint32_t>(
+ IPCMsgFromPlatformToCore::SET_DEFAULT_HEIGHT_AND_WIDTH_INTO_ROOT_DOM),
+ SetDefaultHeightAndWidthIntoRootDom);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::ON_INSTANCE_CLOSE),
+ OnInstanceClose);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::SET_STYLE_WIDTH),
+ SetStyleWidth);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::SET_STYLE_HEIGHT),
+ SetStyleHeight);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::SET_MARGIN), SetMargin);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::SET_PADDING), SetPadding);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::SET_POSITION),
+ SetPosition);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::MARK_DIRTY), MarkDirty);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::SET_VIEWPORT_WIDTH),
+ SetViewPortWidth);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::FORCE_LAYOUT),
+ ForceLayout);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::NOTIFY_LAYOUT),
+ NotifyLayout);
+ handler->registerHandler(
+ static_cast<uint32_t>(
+ IPCMsgFromPlatformToCore::GET_FIRST_SCREEN_RENDER_TIME),
+ GetFirstScreenRenderTime);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::GET_RENDER_FINISH_TIME),
+ GetRenderFinishTime);
+ handler->registerHandler(
+ static_cast<uint32_t>(
+ IPCMsgFromPlatformToCore::SET_RENDER_CONTAINER_WRAP_CONTENT),
+ SetRenderContainerWrapContent);
+ handler->registerHandler(
+ static_cast<uint32_t>(
+ IPCMsgFromPlatformToCore::BIND_MEASUREMENT_TO_RENDER_OBJECT),
+ BindMeasurementToRenderObject);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::REGISTER_CORE_ENV),
+ RegisterCoreEnv);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::GET_RENDER_OBJECT),
+ GetRenderObject);
+ handler->registerHandler(
+ static_cast<uint32_t>(
+ IPCMsgFromPlatformToCore::UPDATE_RENDER_OBJECT_STYLE),
+ UpdateRenderObjectStyle);
+ handler->registerHandler(
+ static_cast<uint32_t>(
+ IPCMsgFromPlatformToCore::UPDATE_RENDER_OBJECT_ATTR),
+ UpdateRenderObjectAttr);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::COPY_RENDER_OBJECT),
+ CopyRenderObject);
+ handler->registerHandler(
+ static_cast<uint32_t>(
+ IPCMsgFromPlatformToCore::SET_MEASURE_FUNCTION_ADAPTER),
+ SetMeasureFunctionAdapter);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::SET_PLATFORM),
+ SetPlatform);
+ handler->registerHandler(
+ static_cast<uint32_t>(
+ IPCMsgFromPlatformToCore::SET_DEVICE_WIDTH_AND_HEIGHT),
+ SetDeviceWidthAndHeight);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::ADD_OPTION), AddOption);
+
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::INIT_FRAMEWORK),
+ InitFramework);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::INIT_APP_FRAMEWORK),
+ InitAppFramework);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::CREATE_APP_CONTEXT),
+ CreateAppContext);
+ handler->registerHandler(
+ static_cast<uint32_t>(
+ IPCMsgFromPlatformToCore::EXEC_JS_ON_APP_WITH_RESULT),
+ ExecJSOnAppWithResult);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::CALL_JS_ON_APP_CONTEXT),
+ CallJSOnAppContext);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::DESTROY_APP_CONTEXT),
+ DestroyAppContext);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::EXEC_JS_SERVICE),
+ ExecJSService);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::EXEC_TIME_CALLBACK),
+ ExecTimerCallback);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::EXEC_JS), ExecJS);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::EXEC_JS_WITH_RESULT),
+ ExecJSWithResult);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::CREATE_INSTANCE),
+ CreateInstance);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::DESTROY_INSTANCE),
+ DestroyInstance);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::EXEC_JS_ON_INSTANCE),
+ ExecJSOnInstance);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCMsgFromPlatformToCore::UPDATE_GLOBAL_CONFIG),
+ UpdateGlobalConfig);
+}
+
+std::unique_ptr<IPCResult>
+PlatformBridgeInMultiProcess::SetDefaultHeightAndWidthIntoRootDom(
+ IPCArguments* arguments) {
+ LOGE("IPC SetDefaultHeightAndWidthIntoRootDom");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ float default_width = arguments->get<float>(1);
+ float default_height = arguments->get<float>(2);
+ bool is_width_wrap_content = arguments->get<bool>(3);
+ bool is_height_wrap_content = arguments->get<bool>(4);
+ Instance()->core_side()->SetDefaultHeightAndWidthIntoRootDom(
+ instance_id, default_width, default_height, is_width_wrap_content,
+ is_height_wrap_content);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::OnInstanceClose(
+ IPCArguments* arguments) {
+ LOGE("IPC OnInstanceClose");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ Instance()->core_side()->OnInstanceClose(instance_id);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::SetStyleWidth(
+ IPCArguments* arguments) {
+ LOGE("IPC SetStyleWidth");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ std::string render_ref(arguments->getByteArray(1)->content,
+ arguments->getByteArray(1)->length);
+ float width = arguments->get<float>(2);
+ Instance()->core_side()->SetStyleWidth(instance_id, render_ref, width);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::SetStyleHeight(
+ IPCArguments* arguments) {
+ LOGE("IPC SetStyleHeight");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ std::string render_ref(arguments->getByteArray(1)->content,
+ arguments->getByteArray(1)->length);
+ float height = arguments->get<float>(2);
+ Instance()->core_side()->SetStyleHeight(instance_id, render_ref, height);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::SetMargin(
+ IPCArguments* arguments) {
+ LOGE("IPC SetMargin");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ std::string render_ref(arguments->getByteArray(1)->content,
+ arguments->getByteArray(1)->length);
+ int edge = arguments->get<int32_t>(2);
+ float value = arguments->get<float>(2);
+ Instance()->core_side()->SetMargin(instance_id, render_ref, edge, value);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::SetPadding(
+ IPCArguments* arguments) {
+ LOGE("IPC SetPadding");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ std::string render_ref(arguments->getByteArray(1)->content,
+ arguments->getByteArray(1)->length);
+ int edge = arguments->get<int32_t>(2);
+ float value = arguments->get<float>(2);
+ Instance()->core_side()->SetPadding(instance_id, render_ref, edge, value);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::SetPosition(
+ IPCArguments* arguments) {
+ LOGE("IPC SetPosition");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ std::string render_ref(arguments->getByteArray(1)->content,
+ arguments->getByteArray(1)->length);
+ int edge = arguments->get<int32_t>(2);
+ float value = arguments->get<float>(3);
+ Instance()->core_side()->SetPadding(instance_id, render_ref, edge, value);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::MarkDirty(
+ IPCArguments* arguments) {
+ LOGE("IPC MarkDirty");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ std::string render_ref(arguments->getByteArray(1)->content,
+ arguments->getByteArray(1)->length);
+ Instance()->core_side()->MarkDirty(instance_id, render_ref);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::SetViewPortWidth(
+ IPCArguments* arguments) {
+ LOGE("IPC SetViewPortWidth");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ float width = arguments->get<float>(1);
+ Instance()->core_side()->SetViewPortWidth(instance_id, width);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::ForceLayout(
+ IPCArguments* arguments) {
+ LOGE("IPC ForceLayout");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ Instance()->core_side()->ForceLayout(instance_id);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::NotifyLayout(
+ IPCArguments* arguments) {
+ LOGE("IPC NotifyLayout");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ auto result = Instance()->core_side()->NotifyLayout(instance_id);
+ return createInt32Result(result);
+}
+
+std::unique_ptr<IPCResult>
+PlatformBridgeInMultiProcess::GetFirstScreenRenderTime(
+ IPCArguments* arguments) {
+ LOGE("IPC GetFirstScreenRenderTime");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ auto result = Instance()->core_side()->GetFirstScreenRenderTime(instance_id);
+ if (result.empty()) {
+ return createVoidResult();
+ } else {
+ int64_t temp[]{result[0], result[1], result[2]};
+ return createByteArrayResult(reinterpret_cast<const char*>(temp),
+ 3 * sizeof(int64_t) / sizeof(char));
+ }
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::GetRenderFinishTime(
+ IPCArguments* arguments) {
+ LOGE("IPC GetRenderFinishTime");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ auto result = Instance()->core_side()->GetRenderFinishTime(instance_id);
+ if (result.empty()) {
+ return createVoidResult();
+ } else {
+ int64_t temp[]{result[0], result[1], result[2]};
+ return createByteArrayResult(reinterpret_cast<const char*>(temp),
+ 3 * sizeof(int64_t) / sizeof(char));
+ }
+}
+
+std::unique_ptr<IPCResult>
+PlatformBridgeInMultiProcess::SetRenderContainerWrapContent(
+ IPCArguments* arguments) {
+ LOGE("IPC SetRenderContainerWrapContent");
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ bool wrap = arguments->get<bool>(1);
+ Instance()->core_side()->SetRenderContainerWrapContent(instance_id, wrap);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult>
+PlatformBridgeInMultiProcess::BindMeasurementToRenderObject(
+ IPCArguments* arguments) {
+ LOGE("IPC BindMeasurementToRenderObject");
+ long ptr = arguments->get<int64_t>(0);
+ Instance()->core_side()->BindMeasurementToRenderObject(ptr);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::RegisterCoreEnv(
+ IPCArguments* arguments) {
+ LOGE("IPC RegisterCoreEnv");
+ std::string key(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ std::string value(arguments->getByteArray(1)->content,
+ arguments->getByteArray(1)->length);
+ Instance()->core_side()->RegisterCoreEnv(key, value);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::GetRenderObject(
+ IPCArguments* arguments) {
+ std::string instance_id(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ std::string render_ref(arguments->getByteArray(1)->content,
+ arguments->getByteArray(1)->length);
+ auto result =
+ Instance()->core_side()->GetRenderObject(instance_id, render_ref);
+ LOGE("IPC GetRenderObject %d", result);
+ return createInt64Result(result);
+}
+std::unique_ptr<IPCResult>
+PlatformBridgeInMultiProcess::UpdateRenderObjectStyle(IPCArguments* arguments) {
+ LOGE("IPC UpdateRenderObjectStyle");
+ long ptr = arguments->get<int64_t>(0);
+ std::string key(arguments->getByteArray(1)->content,
+ arguments->getByteArray(1)->length);
+ std::string value(arguments->getByteArray(2)->content,
+ arguments->getByteArray(2)->length);
+ Instance()->core_side()->UpdateRenderObjectStyle(ptr, key, value);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::UpdateRenderObjectAttr(
+ IPCArguments* arguments) {
+ LOGE("IPC UpdateRenderObjectAttr");
+ long ptr = arguments->get<int64_t>(0);
+ std::string key(arguments->getByteArray(1)->content,
+ arguments->getByteArray(1)->length);
+ std::string value(arguments->getByteArray(2)->content,
+ arguments->getByteArray(2)->length);
+ Instance()->core_side()->UpdateRenderObjectAttr(ptr, key, value);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::CopyRenderObject(
+ IPCArguments* arguments) {
+ LOGE("IPC CopyRenderObject");
+ long ptr = arguments->get<int64_t>(0);
+ auto result = Instance()->core_side()->CopyRenderObject(ptr);
+ return createInt64Result(result);
+}
+
+std::unique_ptr<IPCResult>
+PlatformBridgeInMultiProcess::SetMeasureFunctionAdapter(
+ IPCArguments* arguments) {
+ LOGE("IPC SetMeasureFunctionAdapter");
+ Instance()->core_side()->SetMeasureFunctionAdapter();
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::SetPlatform(
+ IPCArguments* arguments) {
+ LOGE("IPC SetPlatform");
+ std::string platform(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ WeexCore::WXCoreEnvironment::getInstance()->SetPlatform(platform);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult>
+PlatformBridgeInMultiProcess::SetDeviceWidthAndHeight(IPCArguments* arguments) {
+ LOGE("IPC SetDeviceWidthAndHeight");
+ float width = arguments->get<float>(0);
+ float height = arguments->get<float>(1);
+ WeexCore::WXCoreEnvironment::getInstance()->set_device_width(width);
+ WeexCore::WXCoreEnvironment::getInstance()->set_device_height(height);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::AddOption(
+ IPCArguments* arguments) {
+ LOGE("IPC AddOption");
+ std::string key(arguments->getByteArray(0)->content,
+ arguments->getByteArray(0)->length);
+ std::string value(arguments->getByteArray(1)->content,
+ arguments->getByteArray(1)->length);
+ WeexCore::WXCoreEnvironment::getInstance()->AddOption(key, value);
+ return createVoidResult();
+}
+
+static void FillVectorOfValueWithType(std::vector<VALUE_WITH_TYPE*>& params,
+ IPCArguments* arguments, size_t start,
+ size_t end) {
+ for (size_t i = start; i < end; ++i) {
+ auto value = new ValueWithType;
+ switch (arguments->getType(i)) {
+ case IPCType::DOUBLE: {
+ value->type = ParamsType::DOUBLE;
+ value->value.doubleValue = arguments->get<double>(i);
+ } break;
+ case IPCType::STRING: {
+ const IPCString* ipcstr = arguments->getString(i);
+ size_t size = ipcstr->length * sizeof(uint16_t);
+ auto temp = (WeexString*)malloc(size + sizeof(WeexString));
+ memset(temp, 0, size + sizeof(WeexString));
+ temp->length = ipcstr->length;
+ memcpy(temp->content, ipcstr->content, size);
+ value->type = ParamsType::STRING;
+ value->value.string = temp;
+ } break;
+ case IPCType::JSONSTRING: {
+ const IPCString* ipcstr = arguments->getString(i);
+ size_t size = ipcstr->length * sizeof(uint16_t);
+ auto temp = (WeexString*)malloc(size + sizeof(WeexString));
+ memset(temp, 0, size + sizeof(WeexString));
+ temp->length = ipcstr->length;
+ memcpy(temp->content, ipcstr->content, size);
+ value->type = ParamsType::JSONSTRING;
+ value->value.string = temp;
+ } break;
+ case IPCType::BYTEARRAY: {
+ const IPCByteArray* array = arguments->getByteArray(i);
+ size_t size = array->length * sizeof(char);
+ auto temp = (WeexByteArray*)malloc(size + sizeof(WeexByteArray));
+ memset(temp, 0, size + sizeof(WeexByteArray));
+ temp->length = array->length;
+ memcpy(temp->content, array->content, size);
+ value->type = ParamsType::BYTEARRAY;
+ value->value.byteArray = temp;
+ } break;
+ default: { value->type = ParamsType::JSUNDEFINED; } break;
+ }
+ params.push_back(value);
+ }
+}
+
+static void ClearVectorOfValueWithType(std::vector<VALUE_WITH_TYPE*>& params) {
+ for (auto it = params.begin(); it != params.end(); ++it) {
+ switch ((*it)->type) {
+ case ParamsType::STRING:
+ case ParamsType::JSONSTRING:
+ free((*it)->value.string);
+ break;
+ case ParamsType::BYTEARRAY:
+ free((*it)->value.byteArray);
+ break;
+ default:
+ break;
+ }
+ delete *it;
+ }
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::InitFramework(
+ IPCArguments* arguments) {
+ LOGE("IPC InitFramework");
+ // Source
+ const char* source = arguments->getByteArray(0)->content;
+ // Params
+ size_t startCount = 1;
+ size_t count = arguments->getCount();
+ std::vector<INIT_FRAMEWORK_PARAMS*> params;
+ for (size_t i = startCount; i < count; i += 2) {
+ if (arguments->getType(i) != IPCType::BYTEARRAY) {
+ continue;
+ }
+ if (arguments->getType(1 + i) != IPCType::BYTEARRAY) {
+ continue;
+ }
+ const IPCByteArray* ba = arguments->getByteArray(1 + i);
+ const IPCByteArray* ba_type = arguments->getByteArray(i);
+ auto init_framework_params =
+ (INIT_FRAMEWORK_PARAMS*)malloc(sizeof(INIT_FRAMEWORK_PARAMS));
+ if (init_framework_params == nullptr) {
+ break;
+ }
+ memset(init_framework_params, 0, sizeof(INIT_FRAMEWORK_PARAMS));
+ init_framework_params->type = IPCByteArrayToWeexByteArray(ba_type);
+ init_framework_params->value = IPCByteArrayToWeexByteArray(ba);
+ params.push_back(init_framework_params);
+ }
+ return createInt32Result(
+ Instance()->core_side()->InitFramework(source, params));
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::InitAppFramework(
+ IPCArguments* arguments) {
+ const char* id = arguments->getByteArray(0)->content;
+ const char* js = arguments->getByteArray(1)->content;
+ LOGE("Weex jsserver IPCJSMsg::INITAPPFRAMEWORK id:%s", id);
+ if (strcmp(id, "") == 0) {
+ return createInt32Result(static_cast<int32_t>(false));
+ }
+ // Params
+ size_t startCount = 2;
+ size_t count = arguments->getCount();
+ std::vector<INIT_FRAMEWORK_PARAMS*> params;
+ for (size_t i = startCount; i < count; i += 2) {
+ if (arguments->getType(i) != IPCType::BYTEARRAY) {
+ continue;
+ }
+ if (arguments->getType(1 + i) != IPCType::BYTEARRAY) {
+ continue;
+ }
+ const IPCByteArray* ba = arguments->getByteArray(1 + i);
+ const IPCByteArray* ba_type = arguments->getByteArray(i);
+ auto init_framework_params =
+ (INIT_FRAMEWORK_PARAMS*)malloc(sizeof(INIT_FRAMEWORK_PARAMS));
+ if (init_framework_params == nullptr) {
+ break;
+ }
+ memset(init_framework_params, 0, sizeof(INIT_FRAMEWORK_PARAMS));
+ init_framework_params->type = IPCByteArrayToWeexByteArray(ba_type);
+ init_framework_params->value = IPCByteArrayToWeexByteArray(ba);
+ params.push_back(init_framework_params);
+ }
+ return createInt32Result(
+ Instance()->core_side()->InitAppFramework(id, js, params));
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::CreateAppContext(
+ IPCArguments* arguments) {
+ LOGE("IPC CreateAppContext");
+ // LOGE("Weex jsserver IPCJSMsg::CREATEAPPCONTEXT start");
+ const char* instanceID = arguments->getByteArray(0)->content;
+ const char* js = arguments->getByteArray(1)->content;
+ // LOGE("Weex jsserver IPCJSMsg::CREATEAPPCONTEXT end");
+ return createInt32Result(
+ Instance()->core_side()->CreateAppContext(instanceID, js));
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::ExecJSOnAppWithResult(
+ IPCArguments* arguments) {
+ LOGE("IPC ExecJSONAppWithResult");
+ // LOGE("Weex jsserver IPCJSMsg::ExecJSONAppWithResult start");
+ const char* instanceID = arguments->getByteArray(0)->content;
+ const char* js = arguments->getByteArray(1)->content;
+ char* result = const_cast<char*>(
+ Instance()->core_side()->ExecJSOnAppWithResult(instanceID, js));
+
+ if (result == nullptr)
+ return createByteArrayResult(nullptr, 0);
+ else
+ return createCharArrayResult(result);
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::CallJSOnAppContext(
+ IPCArguments* arguments) {
+ LOGE("IPC CallJSONAppContext");
+ // LOGE("Weex jsserver IPCJSMsg::CallJSONAppContext start");
+ const char* instanceId = arguments->getByteArray(0)->content;
+ const char* func = arguments->getByteArray(1)->content;
+
+ std::vector<VALUE_WITH_TYPE*> params;
+ FillVectorOfValueWithType(params, arguments, 2, arguments->getCount());
+ auto result =
+ Instance()->core_side()->CallJSOnAppContext(instanceId, func, params);
+ ClearVectorOfValueWithType(params);
+ return createInt32Result(result);
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::DestroyAppContext(
+ IPCArguments* arguments) {
+ LOGE("IPC DestroyAppContext");
+ // LOGE("Weex jsserver IPCJSMsg::DestroyAppContext start");
+ const char* instanceID = arguments->getByteArray(0)->content;
+ if (strlen(instanceID) == 0) {
+ return createInt32Result(static_cast<int32_t>(false));
+ }
+
+ return createInt32Result(
+ Instance()->core_side()->DestroyAppContext(instanceID));
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::ExecJSService(
+ IPCArguments* arguments) {
+ LOGE("IPC ExecJSService");
+ const char* source = arguments->getByteArray(0)->content;
+ return createInt32Result(Instance()->core_side()->ExecJsService(source));
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::ExecTimerCallback(
+ IPCArguments* arguments) {
+ LOGE("IPC ExecTimerCallback");
+ const char* source = arguments->getByteArray(0)->content;
+ Instance()->core_side()->ExecTimeCallback(source);
+ return createVoidResult();
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::ExecJS(
+ IPCArguments* arguments) {
+ LOGE("IPC ExecJS");
+ const char* instanceId = arguments->getByteArray(0)->content;
+ const char* namespaceStr = arguments->getByteArray(1)->content;
+ const char* func = arguments->getByteArray(2)->content;
+
+ std::vector<VALUE_WITH_TYPE*> params;
+ FillVectorOfValueWithType(params, arguments, 3, arguments->getCount());
+ auto result =
+ Instance()->core_side()->ExecJS(instanceId, namespaceStr, func, params);
+ ClearVectorOfValueWithType(params);
+ return createInt32Result(result);
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::ExecJSWithResult(
+ IPCArguments* arguments) {
+ LOGE("IPC ExecJSWithResult");
+ const char* instanceId = arguments->getByteArray(0)->content;
+ const char* namespaceStr = arguments->getByteArray(1)->content;
+ const char* func = arguments->getByteArray(2)->content;
+
+ std::vector<VALUE_WITH_TYPE*> params;
+ FillVectorOfValueWithType(params, arguments, 3, arguments->getCount());
+ WeexJSResult jsResult = Instance()->core_side()->ExecJSWithResult(
+ instanceId, namespaceStr, func, params);
+ ClearVectorOfValueWithType(params);
+
+ if (jsResult.length <= 0) {
+ return createByteArrayResult(nullptr, 0);
+ }
+ std::unique_ptr<IPCResult> ipcResult =
+ createByteArrayResult(jsResult.data, jsResult.length);
+ WeexJSResultDataFree(jsResult);
+ return ipcResult;
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::CreateInstance(
+ IPCArguments* arguments) {
+ LOGE("IPC CreateInstance");
+
+ const char* instanceID = arguments->getByteArray(0)->content;
+ const char* func = arguments->getByteArray(1)->content;
+ const char* script = arguments->getByteArray(2)->content;
+ const char* opts = arguments->getByteArray(3)->content;
+ const char* initData = arguments->getByteArray(4)->content;
+ const char* extendsApi = arguments->getByteArray(5)->content;
+
+ size_t startCount = 6;
+ size_t count = arguments->getCount();
+ std::vector<INIT_FRAMEWORK_PARAMS*> params;
+ for (size_t i = startCount; i < count; i += 2) {
+ if (arguments->getType(i) != IPCType::BYTEARRAY) {
+ continue;
+ }
+ if (arguments->getType(1 + i) != IPCType::BYTEARRAY) {
+ continue;
+ }
+ const IPCByteArray* ba = arguments->getByteArray(1 + i);
+ const IPCByteArray* ba_type = arguments->getByteArray(i);
+ auto init_framework_params =
+ (INIT_FRAMEWORK_PARAMS*)malloc(sizeof(INIT_FRAMEWORK_PARAMS));
+ if (init_framework_params == nullptr) {
+ break;
+ }
+ memset(init_framework_params, 0, sizeof(INIT_FRAMEWORK_PARAMS));
+ init_framework_params->type = IPCByteArrayToWeexByteArray(ba_type);
+ init_framework_params->value = IPCByteArrayToWeexByteArray(ba);
+ params.push_back(init_framework_params);
+ }
+ return createInt32Result(Instance()->core_side()->CreateInstance(
+ instanceID, func, script, opts, initData, extendsApi,params));
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::DestroyInstance(
+ IPCArguments* arguments) {
+ LOGE("IPC DestroyInstance");
+ const char* instanceID = arguments->getByteArray(0)->content;
+ if (strlen(instanceID) == 0) {
+ LOGE("DestoryInstance instanceId is NULL");
+ return createInt32Result(static_cast<int32_t>(false));
+ }
+
+ return createInt32Result(
+ Instance()->core_side()->DestroyInstance(instanceID));
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::ExecJSOnInstance(
+ IPCArguments* arguments) {
+ LOGE("IPC ExecJSONInstance");
+ const char* instanceID = arguments->getByteArray(0)->content;
+ const char* script = arguments->getByteArray(1)->content;
+
+ char* result = const_cast<char*>(
+ Instance()->core_side()->ExecJSOnInstance(instanceID, script));
+
+ if (result == nullptr)
+ return createByteArrayResult(nullptr, 0);
+ else
+ return createCharArrayResult(result);
+}
+
+std::unique_ptr<IPCResult> PlatformBridgeInMultiProcess::UpdateGlobalConfig(
+ IPCArguments* arguments) {
+ LOGE("IPC UpdateGlobalConfig");
+ const char* configString = arguments->getByteArray(0)->content;
+ Instance()->core_side()->UpdateGlobalConfig(configString);
+ return createVoidResult();
+}
+
+} // namespace weex
diff --git a/weex_core/Source/android/jsengine/bridge/platform/platform_bridge_in_multi_process.h b/weex_core/Source/android/jsengine/bridge/platform/platform_bridge_in_multi_process.h
new file mode 100644
index 0000000000..d951c33b12
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/platform/platform_bridge_in_multi_process.h
@@ -0,0 +1,95 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/12.
+//
+
+#ifndef WEEXV8_PLATFORM_MULTI_PROCESS_BRIDGE_H
+#define WEEXV8_PLATFORM_MULTI_PROCESS_BRIDGE_H
+
+#include "core/bridge/platform_bridge.h"
+
+class IPCHandler;
+class IPCResult;
+class IPCArguments;
+namespace weex {
+class PlatformBridgeInMultiProcess : public WeexCore::PlatformBridge {
+ public:
+ static PlatformBridgeInMultiProcess* Instance() {
+ if (g_instance == NULL) {
+ g_instance = new PlatformBridgeInMultiProcess();
+ }
+ return g_instance;
+ }
+
+ void RegisterIPCCallback(IPCHandler* handler);
+
+ private:
+#define IPC_METHOD(method_name) \
+ static std::unique_ptr<IPCResult> method_name(IPCArguments* arguments);
+
+ IPC_METHOD(SetDefaultHeightAndWidthIntoRootDom)
+ IPC_METHOD(OnInstanceClose)
+ IPC_METHOD(SetStyleWidth)
+ IPC_METHOD(SetStyleHeight)
+ IPC_METHOD(SetMargin)
+ IPC_METHOD(SetPadding)
+ IPC_METHOD(SetPosition)
+ IPC_METHOD(MarkDirty)
+ IPC_METHOD(SetViewPortWidth)
+ IPC_METHOD(ForceLayout)
+ IPC_METHOD(NotifyLayout)
+ IPC_METHOD(GetFirstScreenRenderTime)
+ IPC_METHOD(GetRenderFinishTime)
+ IPC_METHOD(SetRenderContainerWrapContent)
+ IPC_METHOD(BindMeasurementToRenderObject)
+ IPC_METHOD(RegisterCoreEnv)
+ IPC_METHOD(GetRenderObject)
+ IPC_METHOD(UpdateRenderObjectStyle)
+ IPC_METHOD(UpdateRenderObjectAttr)
+ IPC_METHOD(CopyRenderObject)
+ IPC_METHOD(SetMeasureFunctionAdapter)
+ IPC_METHOD(SetPlatform)
+ IPC_METHOD(SetDeviceWidthAndHeight)
+ IPC_METHOD(AddOption)
+
+ IPC_METHOD(InitFramework)
+ IPC_METHOD(InitAppFramework)
+ IPC_METHOD(CreateAppContext)
+ IPC_METHOD(ExecJSOnAppWithResult)
+ IPC_METHOD(CallJSOnAppContext)
+ IPC_METHOD(DestroyAppContext)
+ IPC_METHOD(ExecJSService)
+ IPC_METHOD(ExecTimerCallback)
+ IPC_METHOD(ExecJS)
+ IPC_METHOD(ExecJSWithResult)
+ IPC_METHOD(CreateInstance)
+ IPC_METHOD(ExecJSOnInstance)
+ IPC_METHOD(DestroyInstance)
+ IPC_METHOD(UpdateGlobalConfig)
+
+ private:
+ PlatformBridgeInMultiProcess();
+ virtual ~PlatformBridgeInMultiProcess();
+ static PlatformBridgeInMultiProcess* g_instance;
+ DISALLOW_COPY_AND_ASSIGN(PlatformBridgeInMultiProcess);
+};
+} // namespace weex
+
+#endif // WEEXV8_PLATFORM_MULTI_PROCESS_BRIDGE_H
diff --git a/weex_core/Source/android/jsengine/bridge/platform/platform_bridge_in_multi_so.cpp b/weex_core/Source/android/jsengine/bridge/platform/platform_bridge_in_multi_so.cpp
new file mode 100644
index 0000000000..99e439ccf4
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/platform/platform_bridge_in_multi_so.cpp
@@ -0,0 +1,300 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/12.
+//
+
+#include "platform_bridge_in_multi_so.h"
+#include "android/base/log_utils.h"
+#include "android/jsengine/bridge/script/script_bridge_in_simple.h"
+#include "core/config/core_environment.h"
+#include "core_side_in_simple.h"
+#include "core/manager/weex_core_manager.h"
+#include "include/WeexApiHeader.h"
+#include "platform_side_in_multi_so.h"
+
+static PlatformExposeFunctions *g_platform_expose_functions = nullptr;
+
+// For so to change function to communicate
+extern "C" CoreSideFunctionsOfPlatformBridge *ExchangePlatformBridgeFunctions(
+ PlatformExposeFunctions *platform_expose_functions) {
+ g_platform_expose_functions = platform_expose_functions;
+ return weex::PlatformBridgeInMultiSo::GetExposedFunctions();
+}
+
+namespace weex {
+PlatformBridgeInMultiSo *PlatformBridgeInMultiSo::g_instance = NULL;
+
+PlatformBridgeInMultiSo::PlatformBridgeInMultiSo() {
+ set_core_side(new CoreSideInSimple);
+ set_platform_side(new PlatformSideInMultiSo(g_platform_expose_functions));
+}
+
+PlatformBridgeInMultiSo::~PlatformBridgeInMultiSo() {}
+
+CoreSideFunctionsOfPlatformBridge *
+PlatformBridgeInMultiSo::GetExposedFunctions() {
+ CoreSideFunctionsOfPlatformBridge temp = {SetDefaultHeightAndWidthIntoRootDom,
+ OnInstanceClose,
+ SetStyleWidth,
+ SetStyleHeight,
+ SetMargin,
+ SetPadding,
+ SetPosition,
+ MarkDirty,
+ SetViewPortWidth,
+ ForceLayout,
+ NotifyLayout,
+ GetFirstScreenRenderTime,
+ GetRenderFinishTime,
+ SetRenderContainerWrapContent,
+ BindMeasurementToRenderObject,
+ RegisterCoreEnv,
+ GetRenderObject,
+ UpdateRenderObjectStyle,
+ UpdateRenderObjectAttr,
+ CopyRenderObject,
+ SetMeasureFunctionAdapter,
+ SetPlatform,
+ SetDeviceWidthAndHeight,
+ AddOption,
+ InitFramework,
+ InitAppFramework,
+ CreateAppContext,
+ ExecJSOnAppWithResult,
+ CallJSOnAppContext,
+ DestroyAppContext,
+ ExecJsService,
+ ExecTimeCallback,
+ ExecJS,
+ ExecJSWithResult,
+ CreateInstance,
+ ExecJSOnInstance,
+ DestroyInstance,
+ UpdateGlobalConfig};
+ auto functions = (CoreSideFunctionsOfPlatformBridge *)malloc(
+ sizeof(CoreSideFunctionsOfPlatformBridge));
+ memset(functions, 0, sizeof(CoreSideFunctionsOfPlatformBridge));
+ memcpy(functions, &temp, sizeof(CoreSideFunctionsOfPlatformBridge));
+ return functions;
+}
+
+///////////////////////////
+
+void PlatformBridgeInMultiSo::SetDefaultHeightAndWidthIntoRootDom(
+ const std::string &instance_id, float default_width, float default_height,
+ bool is_width_wrap_content, bool is_height_wrap_content) {
+ g_instance->core_side()->SetDefaultHeightAndWidthIntoRootDom(
+ instance_id, default_width, default_height, is_width_wrap_content,
+ is_height_wrap_content);
+}
+
+void PlatformBridgeInMultiSo::OnInstanceClose(const std::string &instance_id) {
+ LOGE("OnInstanceClose OnInstanceClose");
+ g_instance->core_side()->OnInstanceClose(instance_id);
+}
+
+void PlatformBridgeInMultiSo::SetStyleWidth(const std::string &instance_id,
+ const std::string &render_ref,
+ float width) {
+ g_instance->core_side()->SetStyleWidth(instance_id, render_ref, width);
+}
+
+void PlatformBridgeInMultiSo::SetStyleHeight(const std::string &instance_id,
+ const std::string &render_ref,
+ float height) {
+ g_instance->core_side()->SetStyleHeight(instance_id, render_ref, height);
+}
+
+void PlatformBridgeInMultiSo::SetMargin(const std::string &instance_id,
+ const std::string &render_ref, int edge,
+ float value) {
+ g_instance->core_side()->SetMargin(instance_id, render_ref, edge, value);
+}
+void PlatformBridgeInMultiSo::SetPadding(const std::string &instance_id,
+ const std::string &render_ref,
+ int edge, float value) {
+ g_instance->core_side()->SetPadding(instance_id, render_ref, edge, value);
+}
+
+void PlatformBridgeInMultiSo::SetPosition(const std::string &instance_id,
+ const std::string &render_ref,
+ int edge, float value) {
+ g_instance->core_side()->SetPosition(instance_id, render_ref, edge, value);
+}
+
+void PlatformBridgeInMultiSo::MarkDirty(const std::string &instance_id,
+ const std::string &render_ref) {
+ g_instance->core_side()->MarkDirty(instance_id, render_ref);
+}
+
+void PlatformBridgeInMultiSo::SetViewPortWidth(const std::string &instance_id,
+ float width) {
+ g_instance->core_side()->SetViewPortWidth(instance_id, width);
+}
+
+void PlatformBridgeInMultiSo::ForceLayout(const std::string &instance_id) {
+ g_instance->core_side()->ForceLayout(instance_id);
+}
+
+bool PlatformBridgeInMultiSo::NotifyLayout(const std::string &instance_id) {
+ return g_instance->core_side()->NotifyLayout(instance_id);
+}
+
+std::vector<int64_t> PlatformBridgeInMultiSo::GetFirstScreenRenderTime(
+ const std::string &instance_id) {
+ return g_instance->core_side()->GetFirstScreenRenderTime(instance_id);
+}
+
+std::vector<int64_t> PlatformBridgeInMultiSo::GetRenderFinishTime(
+ const std::string &instance_id) {
+ return g_instance->core_side()->GetRenderFinishTime(instance_id);
+}
+
+void PlatformBridgeInMultiSo::SetRenderContainerWrapContent(
+ const std::string &instance_id, bool wrap) {
+ g_instance->core_side()->SetRenderContainerWrapContent(instance_id, wrap);
+}
+
+void PlatformBridgeInMultiSo::BindMeasurementToRenderObject(long ptr) {
+ g_instance->core_side()->BindMeasurementToRenderObject(ptr);
+}
+
+void PlatformBridgeInMultiSo::RegisterCoreEnv(const std::string &key,
+ const std::string &value) {
+ g_instance->core_side()->RegisterCoreEnv(key, value);
+}
+
+long PlatformBridgeInMultiSo::GetRenderObject(const std::string &instance_id,
+ const std::string &render_ref) {
+ return g_instance->core_side()->GetRenderObject(instance_id, render_ref);
+}
+void PlatformBridgeInMultiSo::UpdateRenderObjectStyle(
+ long render_ptr, const std::string &key, const std::string &value) {
+ g_instance->core_side()->UpdateRenderObjectStyle(render_ptr, key, value);
+}
+
+void PlatformBridgeInMultiSo::UpdateRenderObjectAttr(long render_ptr,
+ const std::string &key,
+ const std::string &value) {
+ g_instance->core_side()->UpdateRenderObjectAttr(render_ptr, key, value);
+}
+
+long PlatformBridgeInMultiSo::CopyRenderObject(long render_ptr) {
+ return g_instance->core_side()->CopyRenderObject(render_ptr);
+}
+
+void PlatformBridgeInMultiSo::SetMeasureFunctionAdapter() {
+ WeexCore::WeexCoreManager::Instance()->set_platform_bridge(
+ PlatformBridgeInMultiSo::Instance());
+ g_instance->core_side()->SetMeasureFunctionAdapter();
+}
+
+void PlatformBridgeInMultiSo::SetPlatform(const std::string &platformName) {
+ WXCoreEnvironment::getInstance()->SetPlatform(platformName);
+}
+
+void PlatformBridgeInMultiSo::SetDeviceWidthAndHeight(float width,
+ float height) {
+ WXCoreEnvironment::getInstance()->set_device_width(width);
+ WXCoreEnvironment::getInstance()->set_device_height(height);
+}
+
+void PlatformBridgeInMultiSo::AddOption(const std::string &key,
+ const std::string &value) {
+ WXCoreEnvironment::getInstance()->AddOption(key, value);
+}
+
+int PlatformBridgeInMultiSo::InitFramework(
+ const char *script, std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) {
+ return Instance()->core_side()->InitFramework(script, params);
+}
+
+int PlatformBridgeInMultiSo::InitAppFramework(
+ const char *instanceId, const char *appFramework,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) {
+ return Instance()->core_side()->InitAppFramework(instanceId, appFramework,
+ params);
+}
+
+int PlatformBridgeInMultiSo::CreateAppContext(const char *instanceId,
+ const char *jsBundle) {
+ return Instance()->core_side()->CreateAppContext(instanceId, jsBundle);
+}
+
+std::unique_ptr<WeexJSResult> PlatformBridgeInMultiSo::ExecJSOnAppWithResult(const char *instanceId,
+ const char *jsBundle) {
+ return const_cast<char *>(
+ Instance()->core_side()->ExecJSOnAppWithResult(instanceId, jsBundle));
+}
+
+int PlatformBridgeInMultiSo::CallJSOnAppContext(
+ const char *instanceId, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ return Instance()->core_side()->CallJSOnAppContext(instanceId, func, params);
+}
+
+int PlatformBridgeInMultiSo::DestroyAppContext(const char *instanceId) {
+ return Instance()->core_side()->DestroyAppContext(instanceId);
+}
+
+int PlatformBridgeInMultiSo::ExecJsService(const char *source) {
+ return Instance()->core_side()->ExecJsService(source);
+}
+
+int PlatformBridgeInMultiSo::ExecTimeCallback(const char *source) {
+ return Instance()->core_side()->ExecTimeCallback(source);
+}
+
+int PlatformBridgeInMultiSo::ExecJS(const char *instanceId,
+ const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ return Instance()->core_side()->ExecJS(instanceId, nameSpace, func, params);
+}
+
+std::unique_ptr<WeexJSResult> PlatformBridgeInMultiSo::ExecJSWithResult(
+ const char *instanceId, const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ return Instance()->core_side()->ExecJSWithResult(instanceId, nameSpace, func,
+ params);
+}
+
+int PlatformBridgeInMultiSo::CreateInstance(
+ const char *instanceId, const char *func, const char *script,
+ const char *opts, const char *initData, const char *extendsApi,
+ std::vector<INIT_FRAMEWORK_PARAMS*>& params) {
+ return Instance()->core_side()->CreateInstance(instanceId, func, script, opts,
+ initData, extendsApi,params);
+}
+
+std::unique_ptr<WeexJSResult> PlatformBridgeInMultiSo::ExecJSOnInstance(const char *instanceId,
+ const char *script) {
+ return const_cast<char *>(
+ Instance()->core_side()->ExecJSOnInstance(instanceId, script));
+}
+
+int PlatformBridgeInMultiSo::DestroyInstance(const char *instanceId) {
+ return Instance()->core_side()->DestroyInstance(instanceId);
+}
+
+int PlatformBridgeInMultiSo::UpdateGlobalConfig(const char *config) {
+ return Instance()->core_side()->UpdateGlobalConfig(config);
+}
+
+} // namespace weex
diff --git a/weex_core/Source/android/jsengine/bridge/platform/platform_bridge_in_multi_so.h b/weex_core/Source/android/jsengine/bridge/platform/platform_bridge_in_multi_so.h
new file mode 100644
index 0000000000..af36487fa1
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/platform/platform_bridge_in_multi_so.h
@@ -0,0 +1,119 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/12.
+//
+
+#ifndef WEEXV8_PLATFORM_MULTI_SO_BRIDGE_H
+#define WEEXV8_PLATFORM_MULTI_SO_BRIDGE_H
+
+#include <map>
+#include <set>
+#include <vector>
+#include "base/common.h"
+#include "core/bridge/platform_bridge.h"
+#include "include/WeexApiHeader.h"
+
+namespace weex {
+
+class PlatformBridgeInMultiSo : public WeexCore::PlatformBridge {
+ public:
+ static PlatformBridgeInMultiSo *Instance() {
+ if (g_instance == NULL) {
+ g_instance = new PlatformBridgeInMultiSo();
+ }
+ return g_instance;
+ }
+
+ static CoreSideFunctionsOfPlatformBridge *GetExposedFunctions();
+ static void SetDefaultHeightAndWidthIntoRootDom(
+ const std::string &instance_id, float default_width, float default_height,
+ bool is_width_wrap_content, bool is_height_wrap_content);
+ static void OnInstanceClose(const std::string &instance_id);
+ static void SetStyleWidth(const std::string &instance_id,
+ const std::string &render_ref, float width);
+ static void SetStyleHeight(const std::string &instance_id,
+ const std::string &render_ref, float height);
+ static void SetMargin(const std::string &instance_id,
+ const std::string &render_ref, int edge, float value);
+ static void SetPadding(const std::string &instance_id,
+ const std::string &render_ref, int edge, float value);
+ static void SetPosition(const std::string &instance_id,
+ const std::string &render_ref, int edge, float value);
+ static void MarkDirty(const std::string &instance_id,
+ const std::string &render_ref);
+ static void SetViewPortWidth(const std::string &instance_id, float width);
+ static void ForceLayout(const std::string &instance_id);
+ static bool NotifyLayout(const std::string &instance_id);
+ static std::vector<int64_t> GetFirstScreenRenderTime(
+ const std::string &instance_id);
+ static std::vector<int64_t> GetRenderFinishTime(
+ const std::string &instance_id);
+ static void SetRenderContainerWrapContent(const std::string &instance_id,
+ bool wrap);
+ static void BindMeasurementToRenderObject(long ptr);
+ static void RegisterCoreEnv(const std::string &key, const std::string &value);
+
+ static long GetRenderObject(const std::string &instance_id,
+ const std::string &render_ref);
+ static void UpdateRenderObjectStyle(long render_ptr, const std::string &key,
+ const std::string &value);
+ static void UpdateRenderObjectAttr(long render_ptr, const std::string &key,
+ const std::string &value);
+ static long CopyRenderObject(long render_ptr);
+ static void SetMeasureFunctionAdapter();
+ static void SetPlatform(const std::string &platformName);
+ static void SetDeviceWidthAndHeight(float width, float height);
+ static void AddOption(const std::string &key, const std::string &value);
+
+ static int InitFramework(const char *script,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms);
+ static int InitAppFramework(const char *instanceId, const char *appFramework,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms);
+ static int CreateAppContext(const char *instanceId, const char *jsBundle);
+ static std::unique_ptr<WeexJSResult> ExecJSOnAppWithResult(const char *instanceId,
+ const char *jsBundle);
+ static int CallJSOnAppContext(const char *instanceId, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms);
+ static int DestroyAppContext(const char *instanceId);
+ static int ExecJsService(const char *source);
+ static int ExecTimeCallback(const char *source);
+ static int ExecJS(const char *instanceId, const char *nameSpace,
+ const char *func, std::vector<VALUE_WITH_TYPE *> ¶ms);
+ static std::unique_ptr<WeexJSResult> ExecJSWithResult(const char *instanceId,
+ const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms);
+ static int CreateInstance(const char *instanceId, const char *func,
+ const char *script, const char *opts,
+ const char *initData, const char *extendsApi,
+ std::vector<INIT_FRAMEWORK_PARAMS*>& params);
+ static std::unique_ptr<WeexJSResult> ExecJSOnInstance(const char *instanceId, const char *script);
+ static int DestroyInstance(const char *instanceId);
+ static int UpdateGlobalConfig(const char *config);
+
+ private:
+ PlatformBridgeInMultiSo();
+ virtual ~PlatformBridgeInMultiSo();
+
+ static PlatformBridgeInMultiSo *g_instance;
+ DISALLOW_COPY_AND_ASSIGN(PlatformBridgeInMultiSo);
+};
+} // namespace weex
+
+#endif // WEEXV8_PLATFORM_MULTI_SO_BRIDGE_H
diff --git a/weex_core/Source/android/jsengine/bridge/platform/platform_side_in_multi_so.cpp b/weex_core/Source/android/jsengine/bridge/platform/platform_side_in_multi_so.cpp
new file mode 100644
index 0000000000..839e27e019
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/platform/platform_side_in_multi_so.cpp
@@ -0,0 +1,203 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/14.
+//
+
+#include "platform_side_in_multi_so.h"
+#include "android/base/log_utils.h"
+#include "core/layout/layout.h"
+
+namespace weex {
+WXCoreSize PlatformSideInMultiSo::InvokeMeasureFunction(
+ const char *page_id, long render_ptr, float width, int width_measure_mode,
+ float height, int height_measure_mode) {
+ return platform_expose_functions_->invoke_measure_function(
+ page_id, render_ptr, width, width_measure_mode, height,
+ height_measure_mode);
+}
+void PlatformSideInMultiSo::InvokeLayoutBefore(const char *page_id,
+ long render_ptr) {
+ platform_expose_functions_->invoke_layout_before(page_id, render_ptr);
+}
+void PlatformSideInMultiSo::InvokeLayoutAfter(const char *page_id,
+ long render_ptr, float width,
+ float height) {
+ platform_expose_functions_->invoke_layout_after(page_id, render_ptr, width,
+ height);
+}
+
+void PlatformSideInMultiSo::SetJSVersion(const char *version) {
+ platform_expose_functions_->set_js_version(version);
+}
+
+void PlatformSideInMultiSo::ReportException(const char *page_id,
+ const char *func,
+ const char *exception_string) {
+ platform_expose_functions_->report_exception(page_id, func, exception_string);
+}
+
+void PlatformSideInMultiSo::ReportServerCrash(const char *instance_id) {
+ platform_expose_functions_->report_server_crash(instance_id);
+}
+
+void PlatformSideInMultiSo::ReportNativeInitStatus(const char *status_code,
+ const char *error_msg) {
+ platform_expose_functions_->report_native_Init_status(status_code, error_msg);
+}
+
+int PlatformSideInMultiSo::CallNative(const char *page_id, const char *task,
+ const char *callback) {
+ return platform_expose_functions_->call_native(page_id, task, callback);
+}
+
+std::unique_ptr<IPCResult> PlatformSideInMultiSo::CallNativeModule(
+ const char *page_id, const char *module, const char *method,
+ const char *arguments, int arguments_length, const char *options,
+ int options_length) {
+ return platform_expose_functions_->call_native_module(
+ page_id, module, method, arguments, arguments_length, options,
+ options_length);
+}
+
+void PlatformSideInMultiSo::CallNativeComponent(
+ const char *page_id, const char *ref, const char *method,
+ const char *arguments, int arguments_length, const char *options,
+ int options_length) {
+ platform_expose_functions_->call_native_component(page_id, ref, method,
+ arguments, arguments_length,
+ options, options_length);
+}
+
+void PlatformSideInMultiSo::SetTimeout(const char *callback_id,
+ const char *time) {
+ platform_expose_functions_->set_timeout(callback_id, time);
+}
+
+void PlatformSideInMultiSo::NativeLog(const char *str_array) {
+ platform_expose_functions_->native_log(str_array);
+}
+
+int PlatformSideInMultiSo::UpdateFinish(const char *page_id, const char *task, int taskLen,
+ const char* callback, int callbackLen) {
+ return platform_expose_functions_->update_finish(page_id, task,taskLen, callback,callbackLen);
+}
+
+int PlatformSideInMultiSo::RefreshFinish(const char *page_id, const char *task,
+ const char *callback) {
+ return platform_expose_functions_->refresh_finish(page_id, task, callback);
+}
+
+int PlatformSideInMultiSo::AddEvent(const char *page_id, const char *ref,
+ const char *event) {
+ return platform_expose_functions_->add_event(page_id, ref, event);
+}
+
+int PlatformSideInMultiSo::RemoveEvent(const char *page_id, const char *ref,
+ const char *event) {
+ return platform_expose_functions_->remove_event(page_id, ref, event);
+}
+
+int PlatformSideInMultiSo::CreateBody(
+ const char *page_id, const char *component_type, const char *ref,
+ std::map<std::string, std::string> *styles,
+ std::map<std::string, std::string> *attributes,
+ std::set<std::string> *events, const WXCoreMargin &margins,
+ const WXCorePadding &paddings, const WXCoreBorderWidth &borders) {
+ return platform_expose_functions_->create_body(page_id, component_type, ref,
+ styles, attributes, events,
+ margins, paddings, borders);
+}
+
+int PlatformSideInMultiSo::AddElement(
+ const char *page_id, const char *component_type, const char *ref,
+ int &index, const char *parentRef,
+ std::map<std::string, std::string> *styles,
+ std::map<std::string, std::string> *attributes,
+ std::set<std::string> *events, const WXCoreMargin &margins,
+ const WXCorePadding &paddings, const WXCoreBorderWidth &borders,
+ bool willLayout) {
+ return platform_expose_functions_->add_element(
+ page_id, component_type, ref, index, parentRef, styles, attributes,
+ events, margins, paddings, borders, willLayout);
+}
+
+int PlatformSideInMultiSo::Layout(const char* page_id, const char* ref, float top,
+ float bottom, float left, float right, float height,
+ float width, bool isRTL, int index) {
+ return platform_expose_functions_->layout(page_id, ref, top, bottom, left,
+ right, height, width, isRTL, index);
+}
+
+int PlatformSideInMultiSo::UpdateStyle(
+ const char *page_id, const char *ref,
+ std::vector<std::pair<std::string, std::string>> *style,
+ std::vector<std::pair<std::string, std::string>> *margin,
+ std::vector<std::pair<std::string, std::string>> *padding,
+ std::vector<std::pair<std::string, std::string>> *border) {
+ return platform_expose_functions_->update_style(page_id, ref, style, margin,
+ padding, border);
+}
+
+int PlatformSideInMultiSo::UpdateAttr(
+ const char *page_id, const char *ref,
+ std::vector<std::pair<std::string, std::string>> *attrs) {
+ return platform_expose_functions_->update_attrs(page_id, ref, attrs);
+}
+
+int PlatformSideInMultiSo::CreateFinish(const char *page_id) {
+ return platform_expose_functions_->create_finish(page_id);
+}
+
+int PlatformSideInMultiSo::RenderSuccess(const char *page_id) {
+ return platform_expose_functions_->render_success(page_id);
+}
+
+int PlatformSideInMultiSo::RemoveElement(const char *page_id, const char *ref) {
+ return platform_expose_functions_->remove_element(page_id, ref);
+}
+
+int PlatformSideInMultiSo::MoveElement(const char *page_id, const char *ref,
+ const char *parent_ref, int index) {
+ return platform_expose_functions_->move_element(page_id, ref, parent_ref,
+ index);
+}
+
+int PlatformSideInMultiSo::AppendTreeCreateFinish(const char *page_id,
+ const char *ref) {
+ return platform_expose_functions_->append_tree_create_finish(page_id, ref);
+}
+
+int PlatformSideInMultiSo::HasTransitionPros(
+ const char *page_id, const char *ref,
+ std::vector<std::pair<std::string, std::string>> *style) {
+ return platform_expose_functions_->has_transition_pros(page_id, ref, style);
+}
+
+void PlatformSideInMultiSo::PostMessage(const char *vm_id, const char *data) {
+ platform_expose_functions_->post_message(vm_id, data);
+}
+
+void PlatformSideInMultiSo::DispatchMessage(const char *client_id,
+ const char *vm_id, const char *data,
+ const char *callback) {
+ platform_expose_functions_->dispatch_message(client_id, vm_id, data,
+ callback);
+}
+} // namespace weex
\ No newline at end of file
diff --git a/weex_core/Source/android/jsengine/bridge/platform/platform_side_in_multi_so.h b/weex_core/Source/android/jsengine/bridge/platform/platform_side_in_multi_so.h
new file mode 100644
index 0000000000..1cc6206f71
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/platform/platform_side_in_multi_so.h
@@ -0,0 +1,128 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/14.
+//
+
+#ifndef WEEXV8_MULTI_SO_PLATFORM_SIDE_H
+#define WEEXV8_MULTI_SO_PLATFORM_SIDE_H
+
+#include "base/common.h"
+#include "core/bridge/platform_bridge.h"
+#include "include/WeexApiHeader.h"
+
+using namespace WeexCore;
+namespace weex {
+class PlatformSideInMultiSo : public WeexCore::PlatformBridge::PlatformSide {
+ public:
+ PlatformSideInMultiSo() {}
+ PlatformSideInMultiSo(PlatformExposeFunctions* platform_expose_functions)
+ : platform_expose_functions_(platform_expose_functions) {}
+ virtual ~PlatformSideInMultiSo() {}
+ inline void set_platform_expose_functions(
+ PlatformExposeFunctions* platform_expose_functions) {
+ platform_expose_functions_ = platform_expose_functions;
+ }
+ WXCoreSize InvokeMeasureFunction(const char* page_id, long render_ptr,
+ float width, int width_measure_mode,
+ float height,
+ int height_measure_mode) override;
+ void InvokeLayoutBefore(const char* page_id, long render_ptr) override;
+ void InvokeLayoutAfter(const char* page_id, long render_ptr, float width,
+ float height) override;
+ void SetJSVersion(const char* version) override;
+ void ReportException(const char* page_id, const char* func,
+ const char* exception_string) override;
+ void ReportServerCrash(const char* instance_id) override;
+ void ReportNativeInitStatus(const char* status_code,
+ const char* error_msg) override;
+ int CallNative(const char* page_id, const char* task,
+ const char* callback) override;
+ std::unique_ptr<IPCResult> CallNativeModule(
+ const char* page_ld, const char* module, const char* method,
+ const char* arguments, int arguments_length, const char* options,
+ int options_length) override;
+ void CallNativeComponent(const char* page_id, const char* ref,
+ const char* method, const char* arguments,
+ int arguments_length, const char* options,
+ int options_length) override;
+ void SetTimeout(const char* callback_id, const char* time) override;
+ void NativeLog(const char* str_array) override;
+ int UpdateFinish(const char* page_id, const char* task, int taskLen,
+ const char* callback, int callbackLen) override;
+ int RefreshFinish(const char* page_id, const char* task,
+ const char* callback) override;
+ int AddEvent(const char* page_id, const char* ref,
+ const char* event) override;
+ int RemoveEvent(const char* page_id, const char* ref,
+ const char* event) override;
+ int CreateBody(const char* pageId, const char* componentType, const char* ref,
+ std::map<std::string, std::string>* styles,
+ std::map<std::string, std::string>* attributes,
+ std::set<std::string>* events, const WXCoreMargin& margins,
+ const WXCorePadding& paddings,
+ const WXCoreBorderWidth& borders) override;
+
+ int AddElement(const char* pageId, const char* componentType, const char* ref,
+ int& index, const char* parentRef,
+ std::map<std::string, std::string>* styles,
+ std::map<std::string, std::string>* attributes,
+ std::set<std::string>* events, const WXCoreMargin& margins,
+ const WXCorePadding& paddings,
+ const WXCoreBorderWidth& borders, bool willLayout) override;
+ int Layout(const char* page_id, const char* ref, float top,
+ float bottom, float left, float right, float height,
+ float width, bool isRTL, int index) override;
+
+ int UpdateStyle(
+ const char* pageId, const char* ref,
+ std::vector<std::pair<std::string, std::string>>* style,
+ std::vector<std::pair<std::string, std::string>>* margin,
+ std::vector<std::pair<std::string, std::string>>* padding,
+ std::vector<std::pair<std::string, std::string>>* border) override;
+ int UpdateAttr(
+ const char* pageId, const char* ref,
+ std::vector<std::pair<std::string, std::string>>* attrs) override;
+
+ int CreateFinish(const char* pageId) override;
+
+ int RenderSuccess(const char* pageId) override;
+
+ int RemoveElement(const char* pageId, const char* ref) override;
+
+ int MoveElement(const char* pageId, const char* ref, const char* parentRef,
+ int index) override;
+
+ int AppendTreeCreateFinish(const char* pageId, const char* ref) override;
+
+ int HasTransitionPros(
+ const char* pageId, const char* ref,
+ std::vector<std::pair<std::string, std::string>>* style) override;
+ void PostMessage(const char* vm_id, const char* data) override;
+ void DispatchMessage(const char* client_id, const char* vm_id,
+ const char* data, const char* callback) override;
+
+ private:
+ // Registered through bridge from other so
+ PlatformExposeFunctions* platform_expose_functions_;
+ DISALLOW_COPY_AND_ASSIGN(PlatformSideInMultiSo);
+};
+} // namespace weex
+
+#endif // WEEXV8_MULTI_SO_PLATFORM_SIDE_H
diff --git a/weex_core/Source/android/jsengine/bridge/platform/platform_side_multi_process.cpp b/weex_core/Source/android/jsengine/bridge/platform/platform_side_multi_process.cpp
new file mode 100644
index 0000000000..868dd21687
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/platform/platform_side_multi_process.cpp
@@ -0,0 +1,745 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#include "platform_side_multi_process.h"
+
+#include "android/jsengine/weex_ipc_server.h"
+#include "core/layout/layout.h"
+#include "third_party/IPC/Buffering/IPCBuffer.h"
+#include "third_party/IPC/IPCResult.h"
+#include "third_party/IPC/IPCSender.h"
+#include "third_party/IPC/Serializing/IPCSerializer.h"
+#include "third_party/IPC/IPCMessageJS.h"
+#include "wson/wson.h"
+
+namespace weex {
+
+inline static void wson_push_type_char_array(wson_buffer *buffer,
+ const char *src, int32_t length) {
+ wson_push_type_uint8_string(buffer, (const uint8_t *)src, length);
+}
+
+WXCoreSize PlatformSideInMultiProcess::InvokeMeasureFunction(
+ const char *page_id, long render_ptr, float width, int width_measure_mode,
+ float height, int height_measure_mode) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::INVOKE_MEASURE_FUNCTION));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(static_cast<int64_t>(render_ptr));
+ serializer->add(width);
+ serializer->add(width_measure_mode);
+ serializer->add(height);
+ serializer->add(height_measure_mode);
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+
+ const char *result_str = result->getByteArrayContent();
+ WXCoreSize size;
+ size.width = reinterpret_cast<const float *>(result_str)[0];
+ size.height = reinterpret_cast<const float *>(result_str)[1];
+ return size;
+}
+void PlatformSideInMultiProcess::InvokeLayoutBefore(const char *page_id,
+ long render_ptr) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::INVOKE_LAYOUT_BEFORE));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(static_cast<int64_t>(render_ptr));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+}
+void PlatformSideInMultiProcess::InvokeLayoutAfter(const char *page_id,
+ long render_ptr, float width,
+ float height) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::INVOKE_LAYOUT_AFTER));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(static_cast<int64_t>(render_ptr));
+ serializer->add(width);
+ serializer->add(height);
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+}
+
+void PlatformSideInMultiProcess::SetJSVersion(const char *version) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::SET_JS_VERSION));
+ serializer->add(version, strlen(version));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+}
+
+void PlatformSideInMultiProcess::ReportException(const char *page_id,
+ const char *func,
+ const char *exception_string) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::REPORT_EXCEPTION));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(func, strlen(func));
+ serializer->add(exception_string, strlen(exception_string));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+}
+
+void PlatformSideInMultiProcess::ReportServerCrash(const char *instance_id) {
+ // TODO
+}
+
+void PlatformSideInMultiProcess::ReportNativeInitStatus(const char *status_code,
+ const char *error_msg) {
+ // TODO
+}
+
+int PlatformSideInMultiProcess::CallNative(const char *page_id,
+ const char *task,
+ const char *callback) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::CALL_NATIVE));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(task, strlen(task));
+ serializer->add(callback, strlen(callback));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ return result->get<int>();
+}
+
+std::unique_ptr<IPCResult> PlatformSideInMultiProcess::CallNativeModule(
+ const char *page_id, const char *module, const char *method,
+ const char *arguments, int arguments_length, const char *options,
+ int options_length) {
+ LOGE("CallNativeModule ipc");
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::CALL_NATIVE_MODULE));
+ serializer->add(page_id, strlen(page_id));
+ // module args[1]
+ serializer->add(module, strlen(module));
+ // method args[2]
+ serializer->add(method, strlen(method));
+ // arguments args[3]
+ serializer->add(arguments, arguments_length);
+ // options args[4]
+ serializer->add(options, options_length);
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ return result;
+}
+
+void PlatformSideInMultiProcess::CallNativeComponent(
+ const char *page_id, const char *ref, const char *method,
+ const char *arguments, int arguments_length, const char *options,
+ int options_length) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::CALL_NATIVE_COMPONENT));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+ serializer->add(method, strlen(method));
+ serializer->add(arguments, arguments_length);
+ serializer->add(arguments_length);
+ serializer->add(options, options_length);
+ serializer->add(options_length);
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+}
+
+void PlatformSideInMultiProcess::SetTimeout(const char *callback_id,
+ const char *time) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::SET_TIMEOUT));
+ serializer->add(callback_id, strlen(callback_id));
+ serializer->add(time, strlen(time));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+}
+
+void PlatformSideInMultiProcess::NativeLog(const char *str_array) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::NATIVE_LOG));
+ serializer->add(str_array, strlen(str_array));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+}
+
+int PlatformSideInMultiProcess::UpdateFinish(const char *page_id,
+ const char *task, int taskLen,
+ const char *callback, int callbackLen) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::UPDATE_FINISH));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(task, strlen(task));
+ serializer->add(callback, strlen(callback));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::RefreshFinish(const char *page_id,
+ const char *task,
+ const char *callback) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::REFRESH_FINISH));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(task, strlen(task));
+ serializer->add(callback, strlen(callback));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::AddEvent(const char *page_id, const char *ref,
+ const char *event) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::ADD_EVENT));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+ serializer->add(event, strlen(event));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::RemoveEvent(const char *page_id,
+ const char *ref,
+ const char *event) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::REMOVE_EVENT));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+ serializer->add(event, strlen(event));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::CreateBody(
+ const char *page_id, const char *component_type, const char *ref,
+ std::map<std::string, std::string> *styles,
+ std::map<std::string, std::string> *attributes,
+ std::set<std::string> *events, const WXCoreMargin &margins,
+ const WXCorePadding &paddings, const WXCoreBorderWidth &borders) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::CREATE_BODY));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(component_type, strlen(component_type));
+ serializer->add(ref, strlen(ref));
+
+ if (styles != nullptr) {
+ wson_buffer *styles_buffer = wson_buffer_new();
+ wson_push_type_map(styles_buffer, styles->size());
+ for (auto it = styles->begin(); it != styles->end(); ++it) {
+ wson_push_type_char_array(styles_buffer, it->first.c_str(),
+ it->first.size());
+ wson_push_type_char_array(styles_buffer, it->second.c_str(),
+ it->second.size());
+ }
+ serializer->add(static_cast<char *>(styles_buffer->data),
+ styles_buffer->position);
+ wson_buffer_free(styles_buffer);
+ } else {
+ serializer->addVoid();
+ }
+
+ if (attributes != nullptr) {
+ wson_buffer *attrs_buffer = wson_buffer_new();
+ wson_push_type_map(attrs_buffer, attributes->size());
+ for (auto it = attributes->begin(); it != attributes->end(); ++it) {
+ wson_push_type_char_array(attrs_buffer, it->first.c_str(),
+ it->first.size());
+ wson_push_type_char_array(attrs_buffer, it->second.c_str(),
+ it->second.size());
+ }
+ serializer->add(static_cast<char *>(attrs_buffer->data),
+ attrs_buffer->position);
+ wson_buffer_free(attrs_buffer);
+ } else {
+ serializer->addVoid();
+ }
+
+ if (events != nullptr) {
+ wson_buffer *events_buffer = wson_buffer_new();
+ wson_push_type_array(events_buffer, events->size());
+ for (auto it = events->begin(); it != events->end(); ++it) {
+ wson_push_type_char_array(events_buffer, (*it).c_str(), (*it).size());
+ }
+ serializer->add(static_cast<char *>(events_buffer->data),
+ events_buffer->position);
+ wson_buffer_free(events_buffer);
+ } else {
+ serializer->addVoid();
+ }
+
+ float margins_buffer[]{
+ margins.getMargin(kMarginTop), margins.getMargin(kMarginBottom),
+ margins.getMargin(kMarginLeft), margins.getMargin(kMarginRight)};
+ serializer->add(reinterpret_cast<uint16_t *>(margins_buffer),
+ 4 * sizeof(float));
+ float paddings_buffer[]{
+ paddings.getPadding(kPaddingTop), paddings.getPadding(kPaddingBottom),
+ paddings.getPadding(kPaddingLeft), paddings.getPadding(kPaddingRight)};
+ serializer->add(reinterpret_cast<uint16_t *>(paddings_buffer),
+ 4 * sizeof(float));
+ float borders_buffer[]{borders.getBorderWidth(kBorderWidthTop),
+ borders.getBorderWidth(kBorderWidthBottom),
+ borders.getBorderWidth(kBorderWidthLeft),
+ borders.getBorderWidth(kBorderWidthRight)};
+ serializer->add(reinterpret_cast<uint16_t *>(borders_buffer),
+ 4 * sizeof(float));
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::AddElement(
+ const char *page_id, const char *component_type, const char *ref,
+ int &index, const char *parentRef,
+ std::map<std::string, std::string> *styles,
+ std::map<std::string, std::string> *attributes,
+ std::set<std::string> *events, const WXCoreMargin &margins,
+ const WXCorePadding &paddings, const WXCoreBorderWidth &borders,
+ bool willLayout) {
+
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::ADD_ELEMENT));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(component_type, strlen(component_type));
+ serializer->add(ref, strlen(ref));
+ serializer->add(index);
+ serializer->add(parentRef, strlen(parentRef));
+
+ if (styles != nullptr) {
+ wson_buffer *styles_buffer = wson_buffer_new();
+ wson_push_type_map(styles_buffer, styles->size());
+ for (auto it = styles->begin(); it != styles->end(); ++it) {
+ wson_push_type_char_array(styles_buffer, it->first.c_str(),
+ it->first.size());
+ wson_push_type_char_array(styles_buffer, it->second.c_str(),
+ it->second.size());
+ }
+ serializer->add(static_cast<char *>(styles_buffer->data),
+ styles_buffer->position);
+ wson_buffer_free(styles_buffer);
+ } else {
+ serializer->addVoid();
+ }
+
+ if (attributes != nullptr) {
+ wson_buffer *attrs_buffer = wson_buffer_new();
+ wson_push_type_map(attrs_buffer, attributes->size());
+ for (auto it = attributes->begin(); it != attributes->end(); ++it) {
+ wson_push_type_char_array(attrs_buffer, it->first.c_str(),
+ it->first.size());
+ wson_push_type_char_array(attrs_buffer, it->second.c_str(),
+ it->second.size());
+ }
+ serializer->add(static_cast<char *>(attrs_buffer->data),
+ attrs_buffer->position);
+ wson_buffer_free(attrs_buffer);
+ } else {
+ serializer->addVoid();
+ }
+
+ if (events != nullptr) {
+ wson_buffer *events_buffer = wson_buffer_new();
+ wson_push_type_array(events_buffer, events->size());
+ for (auto it = events->begin(); it != events->end(); ++it) {
+ wson_push_type_char_array(events_buffer, (*it).c_str(), (*it).size());
+ }
+ serializer->add(static_cast<char *>(events_buffer->data),
+ events_buffer->position);
+ wson_buffer_free(events_buffer);
+ } else {
+ serializer->addVoid();
+ }
+
+ float margins_buffer[]{
+ margins.getMargin(kMarginTop), margins.getMargin(kMarginBottom),
+ margins.getMargin(kMarginLeft), margins.getMargin(kMarginRight)};
+ serializer->add(reinterpret_cast<const char *>(margins_buffer),
+ 4 * sizeof(float));
+ float paddings_buffer[]{
+ paddings.getPadding(kPaddingTop), paddings.getPadding(kPaddingBottom),
+ paddings.getPadding(kPaddingLeft), paddings.getPadding(kPaddingRight)};
+ serializer->add(reinterpret_cast<const char *>(paddings_buffer),
+ 4 * sizeof(float));
+ float borders_buffer[]{borders.getBorderWidth(kBorderWidthTop),
+ borders.getBorderWidth(kBorderWidthBottom),
+ borders.getBorderWidth(kBorderWidthLeft),
+ borders.getBorderWidth(kBorderWidthRight)};
+ serializer->add(reinterpret_cast<const char *>(borders_buffer),
+ 4 * sizeof(float));
+ serializer->add(willLayout);
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::Layout(const char *page_id, const char *ref,
+ int top, int bottom, int left, int right,
+ int height, int width, bool isRTL,
+ int index) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(static_cast<uint32_t>(IPCMsgFromCoreToPlatform::LAYOUT));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+ serializer->add(top);
+ serializer->add(bottom);
+ serializer->add(left);
+ serializer->add(right);
+ serializer->add(height);
+ serializer->add(width);
+ serializer->add(isRTL);
+ serializer->add(index);
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::UpdateStyle(
+ const char *page_id, const char *ref,
+ std::vector<std::pair<std::string, std::string>> *style,
+ std::vector<std::pair<std::string, std::string>> *margin,
+ std::vector<std::pair<std::string, std::string>> *padding,
+ std::vector<std::pair<std::string, std::string>> *border) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::UPDATE_STYLE));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+
+ if (style != nullptr) {
+ wson_buffer *style_buffer = wson_buffer_new();
+ wson_push_type_map(style_buffer, style->size());
+ for (auto it = style->begin(); it != style->end(); ++it) {
+ wson_push_type_char_array(style_buffer, it->first.c_str(),
+ it->first.size());
+ wson_push_type_char_array(style_buffer, it->second.c_str(),
+ it->second.size());
+ }
+ serializer->add(static_cast<char *>(style_buffer->data),
+ style_buffer->position);
+ wson_buffer_free(style_buffer);
+ } else {
+ serializer->addVoid();
+ }
+
+ if (margin != nullptr) {
+ wson_buffer *margin_buffer = wson_buffer_new();
+ wson_push_type_map(margin_buffer, margin->size());
+ for (auto it = margin->begin(); it != margin->end(); ++it) {
+ wson_push_type_char_array(margin_buffer, it->first.c_str(),
+ it->first.size());
+ wson_push_type_char_array(margin_buffer, it->second.c_str(),
+ it->second.size());
+ }
+ serializer->add(static_cast<char *>(margin_buffer->data),
+ margin_buffer->position);
+ wson_buffer_free(margin_buffer);
+ } else {
+ serializer->addVoid();
+ }
+
+ if (padding != nullptr) {
+ wson_buffer *padding_buffer = wson_buffer_new();
+ wson_push_type_map(padding_buffer, padding->size());
+ for (auto it = padding->begin(); it != padding->end(); ++it) {
+ wson_push_type_char_array(padding_buffer, it->first.c_str(),
+ it->first.size());
+ wson_push_type_char_array(padding_buffer, it->second.c_str(),
+ it->second.size());
+ }
+ serializer->add(static_cast<char *>(padding_buffer->data),
+ padding_buffer->position);
+ wson_buffer_free(padding_buffer);
+ } else {
+ serializer->addVoid();
+ }
+
+ if (border != nullptr) {
+ wson_buffer *border_buffer = wson_buffer_new();
+ wson_push_type_map(border_buffer, border->size());
+ for (auto it = border->begin(); it != border->end(); ++it) {
+ wson_push_type_char_array(border_buffer, it->first.c_str(),
+ it->first.size());
+ wson_push_type_char_array(border_buffer, it->second.c_str(),
+ it->second.size());
+ }
+ serializer->add(static_cast<char *>(border_buffer->data),
+ border_buffer->position);
+ wson_buffer_free(border_buffer);
+ } else {
+ serializer->addVoid();
+ }
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::UpdateAttr(
+ const char *page_id, const char *ref,
+ std::vector<std::pair<std::string, std::string>> *attrs) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::UPDATE_ATTR));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+
+ if (attrs != nullptr) {
+ wson_buffer *attrs_buffer = wson_buffer_new();
+ wson_push_type_map(attrs_buffer, attrs->size());
+ for (auto it = attrs->begin(); it != attrs->end(); ++it) {
+ wson_push_type_char_array(attrs_buffer, it->first.c_str(),
+ it->first.size());
+ wson_push_type_char_array(attrs_buffer, it->second.c_str(),
+ it->second.size());
+ }
+ serializer->add(static_cast<char *>(attrs_buffer->data),
+ attrs_buffer->position);
+ wson_buffer_free(attrs_buffer);
+ } else {
+ serializer->addVoid();
+ }
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::CreateFinish(const char *page_id) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::CREATE_FINISH));
+ serializer->add(page_id, strlen(page_id));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::RenderSuccess(const char *page_id) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::RENDER_SUCCESS));
+ serializer->add(page_id, strlen(page_id));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::RemoveElement(const char *page_id,
+ const char *ref) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::REMOVE_ELEMENT));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::MoveElement(const char *page_id,
+ const char *ref,
+ const char *parent_ref, int index) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::MOVE_ELEMENT));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+ serializer->add(parent_ref, strlen(parent_ref));
+ serializer->add(index);
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::AppendTreeCreateFinish(const char *page_id,
+ const char *ref) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(static_cast<uint32_t>(
+ IPCMsgFromCoreToPlatform::APPEND_TREE_CREATE_FINISH));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ return result->get<int>();
+}
+
+int PlatformSideInMultiProcess::HasTransitionPros(
+ const char *page_id, const char *ref,
+ std::vector<std::pair<std::string, std::string>> *style) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::HAS_TRANSITION_PROS));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+
+ if (style != nullptr) {
+ wson_buffer *style_buffer = wson_buffer_new();
+ wson_push_type_map(style_buffer, style->size());
+ auto it = style->begin();
+ for (; it != style->end(); ++it) {
+ wson_push_type_char_array(style_buffer, it->first.c_str(),
+ it->first.size());
+ wson_push_type_char_array(style_buffer, it->second.c_str(),
+ it->second.size());
+ }
+ serializer->add(static_cast<char *>(style_buffer->data),
+ style_buffer->position);
+ wson_buffer_free(style_buffer);
+ } else {
+ serializer->addVoid();
+ }
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+
+ return result->get<int>();
+}
+
+void PlatformSideInMultiProcess::PostMessage(const char *vm_id,
+ const char *data) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::POST_MESSAGE));
+ serializer->add(vm_id, strlen(vm_id));
+ serializer->add(data, strlen(data));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+}
+
+void PlatformSideInMultiProcess::DispatchMessage(const char *client_id,
+ const char *vm_id,
+ const char *data,
+ const char *callback) {
+ WeexIPCClient *pClient = client_;
+
+ IPCSender *sender = pClient->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCMsgFromCoreToPlatform::DISPATCH_MESSAGE));
+ serializer->add(client_id, strlen(client_id));
+ serializer->add(vm_id, strlen(vm_id));
+ serializer->add(data, strlen(data));
+ serializer->add(callback, strlen(callback));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+}
+} // namespace weex
diff --git a/weex_core/Source/android/jsengine/bridge/platform/platform_side_multi_process.h b/weex_core/Source/android/jsengine/bridge/platform/platform_side_multi_process.h
new file mode 100644
index 0000000000..51b6d868df
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/platform/platform_side_multi_process.h
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#ifndef WEEXV8_MULTI_PROCESS_PLATFORM_SIDE_H
+#define WEEXV8_MULTI_PROCESS_PLATFORM_SIDE_H
+
+#include "android/jsengine/weex_ipc_client.h"
+#include "core/bridge/platform_bridge.h"
+
+using namespace WeexCore;
+class WeexJSServer;
+
+namespace weex {
+
+class PlatformSideInMultiProcess : public WeexCore::PlatformBridge::PlatformSide {
+ public:
+ PlatformSideInMultiProcess() {}
+ virtual ~PlatformSideInMultiProcess() {}
+ inline void set_server(WeexJSServer* server) { server_ = server; }
+ inline void set_client(WeexIPCClient* client) {client_ = client; }
+ WXCoreSize InvokeMeasureFunction(const char* page_id, long render_ptr,
+ float width, int width_measure_mode,
+ float height,
+ int height_measure_mode) override;
+ void InvokeLayoutBefore(const char* page_id, long render_ptr) override;
+ void InvokeLayoutAfter(const char* page_id, long render_ptr, float width,
+ float height) override;
+ void SetJSVersion(const char* version) override;
+ void ReportException(const char* page_id, const char* func,
+ const char* exception_string) override;
+ void ReportServerCrash(const char* instance_id) override;
+ void ReportNativeInitStatus(const char* status_code,
+ const char* error_msg) override;
+ int CallNative(const char* page_id, const char* task,
+ const char* callback) override;
+ std::unique_ptr<ValueWithType> CallNativeModule(
+ const char* page_ld, const char* module, const char* method,
+ const char* arguments, int arguments_length, const char* options,
+ int options_length) override;
+ void CallNativeComponent(const char* page_id, const char* ref,
+ const char* method, const char* arguments,
+ int arguments_length, const char* options,
+ int options_length) override;
+ void SetTimeout(const char* callback_id, const char* time) override;
+ void NativeLog(const char* str_array) override;
+ int UpdateFinish(const char* page_id, const char* task, int taskLen,
+ const char* callback, int callbackLen) override;
+ int RefreshFinish(const char* page_id, const char* task,
+ const char* callback) override;
+ int AddEvent(const char* page_id, const char* ref,
+ const char* event) override;
+ int RemoveEvent(const char* page_id, const char* ref,
+ const char* event) override;
+ int CreateBody(const char* pageId, const char* componentType, const char* ref,
+ std::map<std::string, std::string>* styles,
+ std::map<std::string, std::string>* attributes,
+ std::set<std::string>* events, const WXCoreMargin& margins,
+ const WXCorePadding& paddings,
+ const WXCoreBorderWidth& borders) override;
+
+ int AddElement(const char* pageId, const char* componentType, const char* ref,
+ int& index, const char* parentRef,
+ std::map<std::string, std::string>* styles,
+ std::map<std::string, std::string>* attributes,
+ std::set<std::string>* events, const WXCoreMargin& margins,
+ const WXCorePadding& paddings,
+ const WXCoreBorderWidth& borders, bool willLayout) override;
+ int Layout(const char* page_id, const char* ref, float top, float bottom,
+ float left, float right, float height,
+ float width, bool isRTL, int index) override;
+
+ int UpdateStyle(
+ const char* pageId, const char* ref,
+ std::vector<std::pair<std::string, std::string>>* style,
+ std::vector<std::pair<std::string, std::string>>* margin,
+ std::vector<std::pair<std::string, std::string>>* padding,
+ std::vector<std::pair<std::string, std::string>>* border) override;
+ int UpdateAttr(
+ const char* pageId, const char* ref,
+ std::vector<std::pair<std::string, std::string>>* attrs) override;
+
+ int CreateFinish(const char* pageId) override;
+
+ int RenderSuccess(const char* pageId) override;
+
+ int RemoveElement(const char* pageId, const char* ref) override;
+
+ int MoveElement(const char* pageId, const char* ref, const char* parentRef,
+ int index) override;
+
+ int AppendTreeCreateFinish(const char* pageId, const char* ref) override;
+
+ int HasTransitionPros(
+ const char* pageId, const char* ref,
+ std::vector<std::pair<std::string, std::string>>* style) override;
+ void PostMessage(const char* vm_id, const char* data, int dataLength) override;
+ void DispatchMessage(const char* client_id,
+ const char* data, int dataLength, const char* callback, const char* vm_id) override;
+
+ private:
+ WeexJSServer* server_;
+ WeexIPCClient* client_;
+ DISALLOW_COPY_AND_ASSIGN(PlatformSideInMultiProcess);
+};
+
+} // namespace weex
+
+#endif // WEEXV8_MULTI_PROCESS_PLATFORM_SIDE_H
diff --git a/weex_core/Source/android/jsengine/bridge/script/core_side_in_multi_process.cpp b/weex_core/Source/android/jsengine/bridge/script/core_side_in_multi_process.cpp
new file mode 100644
index 0000000000..040701df2c
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/core_side_in_multi_process.cpp
@@ -0,0 +1,602 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#include "core_side_in_multi_process.h"
+#include <unistd.h>
+#include <string>
+#include "android/jsengine/weex_ipc_server.h"
+#include "android/jsengine/weex_jsc_utils.h"
+#include "android/jsengine/object/weex_env.h"
+#include "base/utils/log_utils.h"
+#include "third_party/IPC/Buffering/IPCBuffer.h"
+#include "third_party/IPC/IPCException.h"
+#include "third_party/IPC/IPCResult.h"
+#include "third_party/IPC/IPCSender.h"
+#include "third_party/IPC/IPCType.h"
+#include "third_party/IPC/Serializing/IPCSerializer.h"
+#include "third_party/IPC/IPCMessageJS.h"
+
+namespace weex {
+ namespace bridge {
+ namespace js {
+ CoreSideInMultiProcess::CoreSideInMultiProcess(WeexIPCClient *client)
+ : client_(client) {}
+
+ CoreSideInMultiProcess::CoreSideInMultiProcess() : client_(NULL) {}
+
+ CoreSideInMultiProcess::~CoreSideInMultiProcess() {}
+
+ void CoreSideInMultiProcess::CallNative(const char *page_id, const char *task,
+ const char *callback) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLNATIVE));
+ // instacneID args[0]
+ serializer->add(page_id, strlen(page_id));
+ // task args[1]
+ serializer->add(task, strlen(task));
+ // callback args[2]
+ serializer->add(callback, strlen(callback));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ }
+
+ std::unique_ptr<ValueWithType> CoreSideInMultiProcess::CallNativeModule(
+ const char *page_id, const char *module, const char *method,
+ const char *arguments, int arguments_length, const char *options,
+ int options_length) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLNATIVEMODULE));
+
+ // instacneID args[0]
+ serializer->add(page_id, strlen(page_id));
+ // module args[1]
+ serializer->add(module, strlen(module));
+ // method args[2]
+ serializer->add(method, strlen(method));
+ // arguments args[3]
+ serializer->add(arguments, arguments_length);
+ // options args[4]
+ serializer->add(options, options_length);
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+
+ auto ipc_result = sender->send(buffer.get());
+
+ std::unique_ptr<ValueWithType> ret(new ValueWithType);
+
+ switch (ipc_result->getType()) {
+ case IPCType::DOUBLE:
+ ret->type = ParamsType::DOUBLE;
+ ret->value.doubleValue = ipc_result->get<double>();
+ break;
+ case IPCType::STRING:
+ ret->type = ParamsType::STRING;
+ ret->value.string = genWeexStringSS(ipc_result->getStringContent(), ipc_result->getStringLength());
+ break;
+ case IPCType::JSONSTRING:
+ ret->type = ParamsType::JSONSTRING;
+ ret->value.string = genWeexStringSS(ipc_result->getStringContent(), ipc_result->getStringLength());
+ break;
+ case IPCType::BYTEARRAY: {
+ ret->type = ParamsType::BYTEARRAY;
+ ret->value.byteArray = genWeexByteArraySS(ipc_result->getByteArrayContent(), ipc_result->getByteArrayLength());
+ }
+ break;
+ default:
+ ret->type = ParamsType::JSUNDEFINED;
+ }
+ return ret;
+ }
+
+ void CoreSideInMultiProcess::CallNativeComponent(
+ const char *page_id, const char *ref, const char *method,
+ const char *arguments, int arguments_length, const char *options,
+ int options_length) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLNATIVECOMPONENT));
+
+ // instacneID args[0]
+ serializer->add(page_id, strlen(page_id));
+ // module args[1]
+ serializer->add(ref, strlen(ref));
+ // method args[2]
+ serializer->add(method, strlen(method));
+ // arguments args[3]
+ serializer->add(arguments, arguments_length);
+ // options args[4]
+ serializer->add(options, options_length);
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("functionCallNativeComponent: unexpected result: %d",
+ result->getType());
+ }
+ }
+
+ void CoreSideInMultiProcess::AddElement(const char *page_id,
+ const char *parent_ref,
+ const char *dom_str, int dom_str_length,
+ const char *index_str) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLADDELEMENT) |
+ MSG_FLAG_ASYNC);
+
+ // instacneID args[0]
+ serializer->add(page_id, strlen(page_id));
+ // instacneID args[1]
+ serializer->add(parent_ref, strlen(parent_ref));
+ // dom node args[2]
+ serializer->add(dom_str, dom_str_length);
+ // index args[3]
+ serializer->add(index_str, strlen(index_str));
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ }
+
+ void CoreSideInMultiProcess::SetTimeout(const char *callback_id,
+ const char *time) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::SETTIMEOUT));
+ // callbackId
+ serializer->add(callback_id, strlen(callback_id));
+ // time
+ serializer->add(time, strlen(time));
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("functionCallNativeComponent: unexpected result: %d",
+ result->getType());
+ }
+ }
+
+ void CoreSideInMultiProcess::NativeLog(const char *str_array) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::NATIVELOG) |
+ MSG_FLAG_ASYNC);
+ serializer->add(str_array, strlen(str_array));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ sender->send(buffer.get());
+ }
+
+ void CoreSideInMultiProcess::CreateBody(const char *page_id,
+ const char *dom_str,
+ int dom_str_length) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLCREATEBODY));
+
+ // page id
+ serializer->add(page_id, strlen(page_id));
+ // dom node args[2]
+ serializer->add(dom_str, dom_str_length);
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("functionCallNative: unexpected result: %d", result->getType());
+ }
+ }
+
+ int CoreSideInMultiProcess::UpdateFinish(const char *page_id, const char *task,
+ int task_length, const char *callback,
+ int callback_length) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLUPDATEFINISH));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(task, task_length);
+ serializer->add(callback, callback_length);
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("functionCallUpdateFinish: unexpected result: %d", result->getType());
+ return 0;
+ }
+ return result->get<int32_t>();
+ }
+
+ void CoreSideInMultiProcess::CreateFinish(const char *page_id) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLCREATEFINISH));
+
+ serializer->add(page_id, strlen(page_id));
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("functionCallCreateFinish: unexpected result: %d", result->getType());
+ }
+ }
+
+ int CoreSideInMultiProcess::RefreshFinish(const char *page_id, const char *task,
+ const char *callback) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLREFRESHFINISH));
+ // instacneID args[0]
+ serializer->add(page_id, strlen(page_id));
+ // task args[1]
+ serializer->add(task, strlen(task));
+ // callback args[2]
+ serializer->add(callback, strlen(callback));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("functionCallRefreshFinish: unexpected result: %d", result->getType());
+ return 0;
+ }
+ return result->get<int32_t>();
+ }
+
+ void CoreSideInMultiProcess::UpdateAttrs(const char *page_id, const char *ref,
+ const char *data, int data_length) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLUPDATEATTRS));
+ // instacneID args[0]
+ serializer->add(page_id, strlen(page_id));
+ // ref args[1]
+ serializer->add(ref, strlen(ref));
+ // dom node args[2] TODO
+ serializer->add(data, data_length);
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("functionCallUpdateAttrs: unexpected result: %d", result->getType());
+ }
+ }
+
+ void CoreSideInMultiProcess::UpdateStyle(const char *page_id, const char *ref,
+ const char *data, int data_length) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLUPDATESTYLE));
+ // instacneID args[0]
+ serializer->add(page_id, strlen(page_id));
+ // ref args[1]
+ serializer->add(ref, strlen(ref));
+ // dom node styles args[2]
+ serializer->add(data, data_length);
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("functionCallUpdateStyle: unexpected result: %d", result->getType());
+ }
+ }
+
+ void CoreSideInMultiProcess::RemoveElement(const char *page_id,
+ const char *ref) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLREMOVEELEMENT));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("functionCallRemoveElement: unexpected result: %d", result->getType());
+ }
+ }
+
+ void CoreSideInMultiProcess::MoveElement(const char *page_id, const char *ref,
+ const char *parent_ref, int index) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLMOVEELEMENT));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+ serializer->add(parent_ref, strlen(parent_ref));
+ // Client need string
+ auto temp = std::to_string(index);
+ serializer->add(temp.c_str(), temp.size());
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("functionCallMoveElement: unexpected result: %d", result->getType());
+ }
+ }
+
+ void CoreSideInMultiProcess::AddEvent(const char *page_id, const char *ref,
+ const char *event) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLADDEVENT));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+ serializer->add(event, strlen(event));
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("functionCallAddEvent: unexpected result: %d", result->getType());
+ }
+ }
+
+ void CoreSideInMultiProcess::RemoveEvent(const char *page_id, const char *ref,
+ const char *event) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLREMOVEEVENT));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(ref, strlen(ref));
+ serializer->add(event, strlen(event));
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("functionCallRemoveEvent: unexpected result: %d", result->getType());
+ }
+ }
+
+ const char *CoreSideInMultiProcess::CallGCanvasLinkNative(
+ const char *context_id, int type, const char *arg) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLGCANVASLINK));
+
+ // contextId args[0]
+ serializer->add(context_id, strlen(context_id));
+ // type args[1]
+ serializer->add(type);
+ // arg args[2]
+ serializer->add(arg, strlen(arg));
+
+ try {
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ // LOGE("weexjsc functionGCanvasLinkNative");
+ // if (result->getType() == IPCType::VOID) {
+ // return JSValue::encode(ret);
+ // } else if (result->getStringLength() > 0) {
+ // WTF::String retWString = jString2String(result->getStringContent(),
+ // result->getStringLength()); LOGE("weexjsc functionGCanvasLinkNative
+ // result length > 1 retWString:%s", retWString.utf8().data()); ret =
+ // String2JSValue(state, retWString);
+
+ // }
+ if (result->getType() != IPCType::VOID) {
+ if (result->getStringLength() > 0) {
+ return jString2String(result->getStringContent(),
+ result->getStringLength())
+ .utf8()
+ .data();
+ }
+ }
+ } catch (IPCException &e) {
+ LOGE("functionGCanvasLinkNative exception: %s", e.msg());
+ _exit(1);
+ }
+ return NULL;
+ }
+
+ int CoreSideInMultiProcess::SetInterval(const char *page_id,
+ const char *callback_id,
+ const char *time) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::SETINTERVAL));
+ // instacneID args[0]
+ serializer->add(page_id, strlen(page_id));
+ // task args[1]
+ serializer->add(callback_id, strlen(callback_id));
+ // callback args[2]
+ serializer->add(time, strlen(time));
+ try {
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("functionSetIntervalWeex: unexpected result: %d", result->getType());
+ return 0;
+ }
+ return result->get<int32_t>();
+ } catch (IPCException &e) {
+ LOGE("functionSetIntervalWeex exception %s", e.msg());
+ }
+ return 0;
+ }
+
+ void CoreSideInMultiProcess::ClearInterval(const char *page_id,
+ const char *callback_id) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CLEARINTERVAL));
+ // instacneID args[0]
+ serializer->add(page_id, strlen(page_id));
+ // task args[1]
+ serializer->add(callback_id, strlen(callback_id));
+ try {
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ } catch (IPCException &e) {
+ LOGE("functionClearIntervalWeex exception %s", e.msg());
+ }
+ }
+
+ const char *CoreSideInMultiProcess::CallT3DLinkNative(int type,
+ const char *arg) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::CALLT3DLINK));
+ // type args[1]
+ serializer->add(type);
+ // arg args[2]
+ serializer->add(arg, strlen(arg));
+ try {
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ // LOGE("weexjsc functionT3DLinkNative");
+ // if (result->getType() == IPCType::VOID) {
+ // return JSValue::encode(ret);
+ // } else if (result->getStringLength() > 0) {
+ // WTF::String retWString = jString2String(result->getStringContent(),
+ // result->getStringLength()); LOGE("weexjsc functionT3DLinkNative
+ // result length > 1 retWString:%s", retWString.utf8().data()); ret =
+ // String2JSValue(state, retWString);
+
+ // }
+ if (result->getType() != IPCType::VOID) {
+ if (result->getStringLength() > 0) {
+ return jString2String(result->getStringContent(),
+ result->getStringLength())
+ .utf8()
+ .data();
+ }
+ }
+ } catch (IPCException &e) {
+ LOGE("functionT3DLinkNative exception: %s", e.msg());
+ _exit(1);
+ }
+ return NULL;
+ }
+
+ void CoreSideInMultiProcess::PostMessage(const char *vim_id, const char *data, int dataLength) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::POSTMESSAGE));
+ serializer->add(data, dataLength);
+ serializer->add(vim_id, strlen(vim_id));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ }
+
+ void CoreSideInMultiProcess::DispatchMessage(const char *client_id,
+ const char *data,
+ int dataLength,
+ const char *callback,
+ const char *vm_id) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::DISPATCHMESSAGE));
+ // clientid
+ serializer->add(client_id, strlen(client_id));
+ // data
+ serializer->add(data, dataLength);
+ // callback
+ serializer->add(callback, strlen(callback));
+ serializer->add(vm_id, strlen(vm_id));
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ }
+
+ std::unique_ptr<WeexJSResult>
+ CoreSideInMultiProcess::DispatchMessageSync(const char *client_id,
+ const char *data,
+ int dataLength,
+ const char *vm_id) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(
+ static_cast<uint32_t>(IPCProxyMsg::DISPATCHMESSAGESYNC));
+ // clientid
+ serializer->add(client_id, strlen(client_id));
+ // data
+ serializer->add(data, dataLength);
+ serializer->add(vm_id, strlen(vm_id));
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+
+ char *copy = nullptr;
+ int length = 0;
+ if (result->getType() == IPCType::BYTEARRAY) {
+ length = result->getByteArrayLength();
+ copy = new char[length];
+ strcpy(copy, result->getByteArrayContent());
+ }
+ return std::unique_ptr<WeexJSResult>(
+ new WeexJSResult(std::unique_ptr<char[]>(copy), length));
+ }
+
+ void CoreSideInMultiProcess::ReportException(const char *page_id,
+ const char *func,
+ const char *exception_string) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::REPORTEXCEPTION));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(func, strlen(func));
+ serializer->add(exception_string, strlen(exception_string));
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::VOID) {
+ LOGE("REPORTEXCEPTION: unexpected result: %d", result->getType());
+ }
+ }
+
+ void CoreSideInMultiProcess::SetJSVersion(const char *js_version) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::SETJSFVERSION));
+ serializer->add(js_version, strlen(js_version));
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sender->send(buffer.get());
+ if (result->getType() != IPCType::VOID) {
+ LOGE("setJSFVersion: unexpected result: %d", result->getType());
+ }
+ }
+
+ void CoreSideInMultiProcess::OnReceivedResult(long callback_id, std::unique_ptr<WeexJSResult>& result) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::ONRECEIVEDRESULT));
+ serializer->add(static_cast<int64_t>(callback_id));
+ if (result != nullptr) {
+ serializer->add(result->data.get(), result->length);
+ } else {
+ serializer->addVoid();
+ }
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ sender->send(buffer.get());
+ }
+
+ void CoreSideInMultiProcess::UpdateComponentData(const char* page_id, const char* cid, const char* json_data) {
+ IPCSender *sender = client_->getSender();
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(static_cast<uint32_t>(IPCProxyMsg::UPDATECOMPONENTDATA));
+ serializer->add(page_id, strlen(page_id));
+ serializer->add(cid, strlen(cid));
+ serializer->add(json_data, strlen(json_data));
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ sender->send(buffer.get());
+ }
+ } // namespace js
+ } // namespace bridge
+} // namespace weex
diff --git a/weex_core/Source/android/jsengine/bridge/script/core_side_in_multi_process.h b/weex_core/Source/android/jsengine/bridge/script/core_side_in_multi_process.h
new file mode 100644
index 0000000000..6cab646073
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/core_side_in_multi_process.h
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#ifndef WEEXV8_MULTI_PROCESS_CORE_SIDE_H
+#define WEEXV8_MULTI_PROCESS_CORE_SIDE_H
+
+ #include <memory>
+#include "android/jsengine/weex_ipc_client.h"
+#include "core/bridge/script_bridge.h"
+
+class WeexJSServer;
+namespace weex {
+ namespace bridge {
+ namespace js {
+ class CoreSideInMultiProcess : public WeexCore::ScriptBridge::CoreSide {
+ public:
+ explicit CoreSideInMultiProcess(WeexIPCClient *client);
+ explicit CoreSideInMultiProcess();
+
+ ~CoreSideInMultiProcess() override;
+
+ inline void set_ipc_client(WeexIPCClient *client) { client_ = client; };
+
+ void CallNative(const char *page_id, const char *task,
+ const char *callback) override;
+
+ std::unique_ptr<ValueWithType> CallNativeModule(
+ const char *page_id, const char *module, const char *method,
+ const char *arguments, int arguments_length, const char *options,
+ int options_length) override;
+
+ void CallNativeComponent(const char *page_id, const char *ref,
+ const char *method, const char *arguments,
+ int arguments_length, const char *options,
+ int options_length) override;
+
+ void AddElement(const char *page_id, const char *parent_ref,
+ const char *dom_str, int dom_str_length,
+ const char *index_str) override;
+
+ void SetTimeout(const char *callback_id, const char *time) override;
+
+ void NativeLog(const char *str_array) override;
+
+ void CreateBody(const char *page_id, const char *dom_str,
+ int dom_str_length) override;
+
+ int UpdateFinish(const char *page_id, const char *task, int task_length,
+ const char *callback, int callback_length) override;
+
+ void CreateFinish(const char *page_id) override;
+
+ int RefreshFinish(const char *page_id, const char *task,
+ const char *callback) override;
+
+ void UpdateAttrs(const char *page_id, const char *ref, const char *data,
+ int data_length) override;
+
+ void UpdateStyle(const char *page_id, const char *ref, const char *data,
+ int data_length) override;
+
+ void RemoveElement(const char *page_id, const char *ref) override;
+
+ void MoveElement(const char *page_id, const char *ref, const char *parent_ref,
+ int index) override;
+
+ void AddEvent(const char *page_id, const char *ref,
+ const char *event) override;
+
+ void RemoveEvent(const char *page_id, const char *ref,
+ const char *event) override;
+
+ const char *CallGCanvasLinkNative(const char *context_id, int type,
+ const char *arg) override;
+
+ int SetInterval(const char *page_id, const char *callback_id,
+ const char *time) override;
+
+ void ClearInterval(const char *page_id, const char *callback_id) override;
+
+ const char *CallT3DLinkNative(int type, const char *arg) override;
+
+ void PostMessage(const char *vim_id, const char *data, int dataLength) override;
+
+ void DispatchMessage(const char *client_id, const char *data, int dataLength,
+ const char *callback, const char *vm_id) override;
+
+ std::unique_ptr<WeexJSResult> DispatchMessageSync(
+ const char *client_id, const char *data, int dataLength,
+ const char *vm_id) override;
+
+ void ReportException(const char *page_id, const char *func,
+ const char *exception_string) override;
+
+ void SetJSVersion(const char *js_version) override;
+
+ void OnReceivedResult(long callback_id, std::unique_ptr<WeexJSResult>& result);
+ void UpdateComponentData(const char* page_id, const char* cid, const char* json_data);
+
+ private:
+ WeexIPCClient *client_;
+ DISALLOW_COPY_AND_ASSIGN(CoreSideInMultiProcess);
+ };
+ } // namespace js
+ } // namespace bridge
+} // namespace weex
+
+#endif // WEEXV8_MULTI_PROCESS_CORE_SIDE_H
diff --git a/weex_core/Source/android/jsengine/bridge/script/core_side_in_multi_so.cpp b/weex_core/Source/android/jsengine/bridge/script/core_side_in_multi_so.cpp
new file mode 100644
index 0000000000..b18270a6b0
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/core_side_in_multi_so.cpp
@@ -0,0 +1,185 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#include "core_side_in_multi_so.h"
+
+#include "android/jsengine/object/args.h"
+#include "base/android/log_utils.h"
+#include "include/WeexApiHeader.h"
+
+namespace weex {
+namespace bridge {
+namespace js {
+
+void CoreSideInMultiSo::CallNative(const char *page_id, const char *task,
+ const char *callback) {
+ functions_exposed_by_core_->funcCallNative(page_id, task, callback);
+}
+
+std::unique_ptr<ValueWithType> CoreSideInMultiSo::CallNativeModule(
+ const char *page_id, const char *module, const char *method,
+ const char *arguments, int arguments_length, const char *options,
+ int options_length) {
+ return functions_exposed_by_core_->funcCallNativeModule(
+ page_id, module, method, arguments, arguments_length, options,
+ options_length);
+}
+
+void CoreSideInMultiSo::CallNativeComponent(const char *page_id,
+ const char *ref, const char *method,
+ const char *arguments,
+ int arguments_length,
+ const char *options,
+ int options_length) {
+ functions_exposed_by_core_->funcCallNativeComponent(
+ page_id, ref, method, arguments, arguments_length, options,
+ options_length);
+}
+
+void CoreSideInMultiSo::AddElement(const char *page_id, const char *parent_ref,
+ const char *dom_str, int dom_str_length,
+ const char *index_str) {
+ functions_exposed_by_core_->funcCallAddElement(page_id, parent_ref, dom_str, dom_str_length,
+ index_str);
+}
+
+void CoreSideInMultiSo::SetTimeout(const char *callback_id, const char *time) {
+ functions_exposed_by_core_->funcSetTimeout(callback_id, time);
+}
+
+void CoreSideInMultiSo::NativeLog(const char *str_array) {
+ functions_exposed_by_core_->funcCallNativeLog(str_array);
+}
+
+void CoreSideInMultiSo::CreateBody(const char *page_id, const char *dom_str,
+ int dom_str_length) {
+ functions_exposed_by_core_->funcCallCreateBody(page_id, dom_str, dom_str_length);
+}
+
+int CoreSideInMultiSo::UpdateFinish(const char *page_id, const char *task,
+ int task_length, const char *callback,
+ int callback_length) {
+ return functions_exposed_by_core_->funcCallUpdateFinish(page_id, task, task_length,
+ callback, callback_length);
+}
+
+void CoreSideInMultiSo::CreateFinish(const char *page_id) {
+ functions_exposed_by_core_->funcCallCreateFinish(page_id);
+}
+
+int CoreSideInMultiSo::RefreshFinish(const char *page_id, const char *task,
+ const char *callback) {
+ return functions_exposed_by_core_->funcCallRefreshFinish(page_id, task,
+ callback);
+}
+
+void CoreSideInMultiSo::UpdateAttrs(const char *page_id, const char *ref,
+ const char *data, int data_length) {
+ functions_exposed_by_core_->funcCallUpdateAttrs(page_id, ref, data, data_length);
+}
+
+void CoreSideInMultiSo::UpdateStyle(const char *page_id, const char *ref,
+ const char *data, int data_length) {
+ functions_exposed_by_core_->funcCallUpdateStyle(page_id, ref, data, data_length);
+}
+
+void CoreSideInMultiSo::RemoveElement(const char *page_id, const char *ref) {
+ functions_exposed_by_core_->funcCallRemoveElement(page_id, ref);
+}
+
+void CoreSideInMultiSo::MoveElement(const char *page_id, const char *ref,
+ const char *parent_ref, int index) {
+ functions_exposed_by_core_->funcCallMoveElement(page_id, ref, parent_ref,
+ index);
+}
+
+void CoreSideInMultiSo::AddEvent(const char *page_id, const char *ref,
+ const char *event) {
+ functions_exposed_by_core_->funcCallAddEvent(page_id, ref, event);
+}
+
+void CoreSideInMultiSo::RemoveEvent(const char *page_id, const char *ref,
+ const char *event) {
+ functions_exposed_by_core_->funcCallRemoveEvent(page_id, ref, event);
+}
+
+const char *CoreSideInMultiSo::CallGCanvasLinkNative(const char *context_id,
+ int type,
+ const char *arg) {
+ return functions_exposed_by_core_->funcCallGCanvasLinkNative(context_id, type,
+ arg);
+}
+
+int CoreSideInMultiSo::SetInterval(const char *page_id, const char *callback_id,
+ const char *time) {
+ return functions_exposed_by_core_->funcSetInterval(page_id, callback_id,
+ time);
+}
+
+void CoreSideInMultiSo::ClearInterval(const char *page_id,
+ const char *callback_id) {
+// LOGE("CoreSideInMultiSo::ClearInterval");
+ functions_exposed_by_core_->funcClearInterval(page_id, callback_id);
+}
+
+const char *CoreSideInMultiSo::CallT3DLinkNative(int type, const char *arg) {
+ return functions_exposed_by_core_->funcT3dLinkNative(type, arg);
+}
+
+void CoreSideInMultiSo::PostMessage(const char *vim_id, const char *data, int dataLength) {
+ functions_exposed_by_core_->funcCallHandlePostMessage(vim_id, data, dataLength);
+}
+
+void CoreSideInMultiSo::DispatchMessage(const char *client_id, const char *data, int dataLength,
+ const char *callback,
+ const char *vm_id) {
+ functions_exposed_by_core_->funcCallDIspatchMessage(client_id, data,dataLength, callback,
+ vm_id);
+}
+
+std::unique_ptr<WeexJSResult> CoreSideInMultiSo::DispatchMessageSync(
+ const char *client_id, const char *data, int dataLength,
+ const char *vm_id) {
+ return functions_exposed_by_core_->funcCallDispatchMessageSync(client_id, data,
+ dataLength, vm_id);
+}
+
+void CoreSideInMultiSo::ReportException(const char *page_id, const char *func,
+ const char *exception_string) {
+ functions_exposed_by_core_->funcReportException(page_id, func,
+ exception_string);
+}
+
+void CoreSideInMultiSo::SetJSVersion(const char *js_version) {
+ functions_exposed_by_core_->funcSetJSVersion(js_version);
+}
+
+void CoreSideInMultiSo::OnReceivedResult(long callback_id, std::unique_ptr<WeexJSResult>& result) {
+ functions_exposed_by_core_->funcOnReceivedResult(callback_id, result);
+}
+
+void CoreSideInMultiSo::UpdateComponentData(const char* page_id, const char* cid, const char* json_data) {
+ functions_exposed_by_core_->funcUpdateComponentData(page_id, cid, json_data);
+}
+} // namespace js
+} // namespace bridge
+} // namespace weex
diff --git a/weex_core/Source/android/jsengine/bridge/script/core_side_in_multi_so.h b/weex_core/Source/android/jsengine/bridge/script/core_side_in_multi_so.h
new file mode 100644
index 0000000000..625a9755ef
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/core_side_in_multi_so.h
@@ -0,0 +1,102 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#ifndef WEEXV8_MULTI_SO_CORE_SIDE_H
+#define WEEXV8_MULTI_SO_CORE_SIDE_H
+
+#include "core/bridge/script_bridge.h"
+
+namespace weex {
+namespace bridge {
+namespace js {
+class CoreSideInMultiSo : public WeexCore::ScriptBridge::CoreSide {
+ public:
+ explicit CoreSideInMultiSo(){};
+ explicit CoreSideInMultiSo(FunctionsExposedByCore *functions_exposed_by_core)
+ : functions_exposed_by_core_(functions_exposed_by_core){};
+ inline void set_functions_exposed_by_core(
+ FunctionsExposedByCore *functions_exposed_by_core) {
+ functions_exposed_by_core_ = functions_exposed_by_core;
+ }
+ ~CoreSideInMultiSo() override{};
+
+ void CallNative(const char *page_id, const char *task,
+ const char *callback) override;
+ std::unique_ptr<ValueWithType> CallNativeModule(
+ const char *page_id, const char *module, const char *method,
+ const char *arguments, int arguments_length, const char *options,
+ int options_length) override;
+ void CallNativeComponent(const char *page_id, const char *ref,
+ const char *method, const char *arguments,
+ int arguments_length, const char *options,
+ int options_length) override;
+ void AddElement(const char *page_id, const char *parent_ref,
+ const char *dom_str, int dom_str_length,
+ const char *index_str) override;
+ void SetTimeout(const char *callback_id, const char *time) override;
+ void NativeLog(const char *str_array) override;
+ void CreateBody(const char *page_id, const char *dom_str,
+ int dom_str_length) override;
+ int UpdateFinish(const char *page_id, const char *task, int task_length,
+ const char *callback, int callback_length) override;
+ void CreateFinish(const char *page_id) override;
+ int RefreshFinish(const char *page_id, const char *task,
+ const char *callback) override;
+ void UpdateAttrs(const char *page_id, const char *ref, const char *data,
+ int data_length) override;
+ void UpdateStyle(const char *page_id, const char *ref, const char *data,
+ int data_length) override;
+ void RemoveElement(const char *page_id, const char *ref) override;
+ void MoveElement(const char *page_id, const char *ref, const char *parent_ref,
+ int index) override;
+ void AddEvent(const char *page_id, const char *ref,
+ const char *event) override;
+ void RemoveEvent(const char *page_id, const char *ref,
+ const char *event) override;
+ const char *CallGCanvasLinkNative(const char *context_id, int type,
+ const char *arg) override;
+ int SetInterval(const char *page_id, const char *callback_id,
+ const char *time) override;
+ void ClearInterval(const char *page_id, const char *callback_id) override;
+ const char *CallT3DLinkNative(int type, const char *arg) override;
+ void PostMessage(const char *vim_id, const char *data, int dataLength) override;
+ void DispatchMessage(const char *client_id, const char *data, int dataLength,
+ const char *callback, const char *vm_id) override;
+ std::unique_ptr<WeexJSResult> DispatchMessageSync(const char *client_id,
+ const char *data,
+ int dataLength,
+ const char *vm_id) override;
+ void ReportException(const char *page_id, const char *func,
+ const char *exception_string) override;
+ void SetJSVersion(const char *js_version) override;
+ void OnReceivedResult(long callback_id, std::unique_ptr<WeexJSResult>& result);
+ void UpdateComponentData(const char* page_id, const char* cid, const char* json_data);
+
+ private:
+ FunctionsExposedByCore *functions_exposed_by_core_;
+ DISALLOW_COPY_AND_ASSIGN(CoreSideInMultiSo);
+};
+} // namespace js
+} // namespace bridge
+} // namespace weex
+
+#endif // WEEXV8_MULTI_SO_CORE_SIDE_H
diff --git a/weex_core/Source/android/jsengine/bridge/script/core_side_in_simple.cpp b/weex_core/Source/android/jsengine/bridge/script/core_side_in_simple.cpp
new file mode 100644
index 0000000000..2b2eea4a05
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/core_side_in_simple.cpp
@@ -0,0 +1,228 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#include "core_side_in_simple.h"
+
+#include "android/jsengine/object/args.h"
+#include "base/android/log_utils.h"
+#include "base/android/log_utils.h"
+#include "core/manager/weex_core_manager.h"
+#include "core/render/manager/render_manager.h"
+#include "third_party/IPC/IPCResult.h"
+
+namespace weex {
+namespace bridge {
+namespace js {
+CoreSideInSimple::CoreSideInSimple() {}
+
+CoreSideInSimple::~CoreSideInSimple() {}
+
+void CoreSideInSimple::CallNative(const char *page_id, const char *task,
+ const char *callback) {
+ if (page_id == nullptr || task == nullptr) return;
+ if (strcmp(
+ task,
+ "[{\"module\":\"dom\",\"method\":\"createFinish\",\"args\":[]}]") ==
+ 0) {
+ RenderManager::GetInstance()->CreateFinish(page_id) ? 0 : -1;
+ } else {
+ WeexCoreManager::Instance()
+ ->getPlatformBridge()
+ ->platform_side()
+ ->CallNative(page_id, task, callback);
+ }
+}
+
+std::unique_ptr<IPCResult> CoreSideInSimple::CallNativeModule(
+ const char *page_id, const char *module, const char *method,
+ const char *arguments, int arguments_length, const char *options,
+ int options_length) {
+ std::unique_ptr<IPCResult> ret = createInt32Result(-1);
+ if (page_id != nullptr && module != nullptr && method != nullptr) {
+ RenderManager::GetInstance()->CallNativeModule(page_id, module, method,
+ arguments, arguments_length,
+ options, options_length);
+
+ return WeexCoreManager::Instance()
+ ->getPlatformBridge()
+ ->platform_side()
+ ->CallNativeModule(page_id, module, method, arguments, arguments_length,
+ options, options_length);
+ }
+
+ return ret;
+}
+
+void CoreSideInSimple::CallNativeComponent(const char *page_id, const char *ref,
+ const char *method,
+ const char *arguments,
+ int arguments_length,
+ const char *options,
+ int options_length) {
+ if (page_id != nullptr && ref != nullptr && method != nullptr) {
+ WeexCoreManager::Instance()
+ ->getPlatformBridge()
+ ->platform_side()
+ ->CallNativeComponent(page_id, ref, method, arguments, arguments_length,
+ options, options_length);
+ }
+}
+
+void CoreSideInSimple::AddElement(const char *page_id, const char *parent_ref,
+ const char *dom_str, int dom_str_length,
+ const char *index_str) {
+ const char *indexChar = index_str == nullptr ? "\0" : index_str;
+
+ int index = atoi(indexChar);
+ if (page_id == nullptr || parent_ref == nullptr || dom_str == nullptr ||
+ index < -1)
+ return;
+
+ RenderManager::GetInstance()->AddRenderObject(page_id, parent_ref, index,
+ dom_str);
+}
+
+void CoreSideInSimple::SetTimeout(const char *callback_id, const char *time) {
+ WeexCoreManager::Instance()
+ ->getPlatformBridge()
+ ->platform_side()
+ ->SetTimeout(callback_id, time);
+}
+
+void CoreSideInSimple::NativeLog(const char *str_array) {
+ WeexCoreManager::Instance()
+ ->getPlatformBridge()
+ ->platform_side()
+ ->NativeLog(str_array);
+}
+
+void CoreSideInSimple::CreateBody(const char *page_id, const char *dom_str,
+ int dom_str_length) {
+ RenderManager::GetInstance()->CreatePage(page_id, dom_str) ? 0 : -1;
+}
+
+int CoreSideInSimple::UpdateFinish(const char *page_id, const char *task,
+ int task_length, const char *callback,
+ int callback_length) {
+ return WeexCoreManager::Instance()
+ ->getPlatformBridge()
+ ->platform_side()
+ ->UpdateFinish(page_id, task,task_length, callback,callback_length);
+}
+
+void CoreSideInSimple::CreateFinish(const char *page_id) {
+ RenderManager::GetInstance()->CreateFinish(page_id);
+}
+
+int CoreSideInSimple::RefreshFinish(const char *page_id, const char *task,
+ const char *callback) {
+ if (page_id == nullptr) return -1;
+ return WeexCoreManager::Instance()
+ ->getPlatformBridge()
+ ->platform_side()
+ ->RefreshFinish(page_id, task, callback);
+}
+
+void CoreSideInSimple::UpdateAttrs(const char *page_id, const char *ref,
+ const char *data, int data_length) {
+ RenderManager::GetInstance()->UpdateAttr(page_id, ref, data);
+}
+
+void CoreSideInSimple::UpdateStyle(const char *page_id, const char *ref,
+ const char *data, int data_length) {
+ RenderManager::GetInstance()->UpdateStyle(page_id, ref, data);
+}
+
+void CoreSideInSimple::RemoveElement(const char *page_id, const char *ref) {
+ RenderManager::GetInstance()->RemoveRenderObject(page_id, ref);
+}
+
+void CoreSideInSimple::MoveElement(const char *page_id, const char *ref,
+ const char *parent_ref, int index) {
+ RenderManager::GetInstance()->MoveRenderObject(page_id, ref, parent_ref,
+ index);
+}
+
+void CoreSideInSimple::AddEvent(const char *page_id, const char *ref,
+ const char *event) {
+ RenderManager::GetInstance()->AddEvent(page_id, ref, event);
+}
+
+void CoreSideInSimple::RemoveEvent(const char *page_id, const char *ref,
+ const char *event) {
+ RenderManager::GetInstance()->RemoveEvent(page_id, ref, event);
+}
+
+const char *CoreSideInSimple::CallGCanvasLinkNative(const char *context_id,
+ int type, const char *arg) {
+ // TODO
+ return NULL;
+}
+
+int CoreSideInSimple::SetInterval(const char *page_id, const char *callback_id,
+ const char *time) {
+ return (atoi(page_id) << 16) | (atoi(callback_id));
+}
+
+void CoreSideInSimple::ClearInterval(const char *page_id,
+ const char *callback_id) {
+ // do nothing
+}
+
+const char *CoreSideInSimple::CallT3DLinkNative(int type, const char *arg) {
+ // TODO
+ return NULL;
+}
+void CoreSideInSimple::PostMessage(const char *vm_id, const char *data) {
+ WeexCoreManager::Instance()
+ ->getPlatformBridge()
+ ->platform_side()
+ ->PostMessage(vm_id, data);
+}
+
+void CoreSideInSimple::DispatchMessage(const char *client_id, const char *data,
+ const char *callback,
+ const char *vm_id) {
+ WeexCoreManager::Instance()
+ ->getPlatformBridge()
+ ->platform_side()
+ ->DispatchMessage(client_id, vm_id, data, callback);
+}
+
+void CoreSideInSimple::ReportException(const char *page_id, const char *func,
+ const char *exception_string) {
+ WeexCoreManager::Instance()
+ ->getPlatformBridge()
+ ->platform_side()
+ ->ReportException(page_id, func, exception_string);
+}
+
+void CoreSideInSimple::SetJSVersion(const char *js_version) {
+ LOGA("init JSFrm version %s", js_version);
+ WeexCoreManager::Instance()
+ ->getPlatformBridge()
+ ->platform_side()
+ ->SetJSVersion(js_version);
+}
+} // namespace js
+} // namespace bridge
+} // namespace weex
diff --git a/weex_core/Source/android/jsengine/bridge/script/core_side_in_simple.h b/weex_core/Source/android/jsengine/bridge/script/core_side_in_simple.h
new file mode 100644
index 0000000000..ad148d0e0d
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/core_side_in_simple.h
@@ -0,0 +1,89 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#ifndef WEEXV8_SIMPLE_CORE_SIDE_H
+#define WEEXV8_SIMPLE_CORE_SIDE_H
+
+#include "core/bridge/script_bridge.h"
+
+namespace weex {
+namespace bridge {
+namespace js {
+class CoreSideInSimple : public WeexCore::ScriptBridge::CoreSide {
+ public:
+ explicit CoreSideInSimple();
+ ~CoreSideInSimple() override;
+
+ void CallNative(const char *page_id, const char *task,
+ const char *callback) override;
+ std::unique_ptr<ValueWithType> CallNativeModule(
+ const char *page_id, const char *module, const char *method,
+ const char *arguments, int arguments_length, const char *options,
+ int options_length) override;
+ void CallNativeComponent(const char *page_id, const char *ref,
+ const char *method, const char *arguments,
+ int arguments_length, const char *options,
+ int options_length) override;
+ void AddElement(const char *page_id, const char *parent_ref,
+ const char *dom_str, int dom_str_length,
+ const char *index_str) override;
+ void SetTimeout(const char *callback_id, const char *time) override;
+ void NativeLog(const char *str_array) override;
+ void CreateBody(const char *page_id, const char *dom_str,
+ int dom_str_length) override;
+ int UpdateFinish(const char *page_id, const char *task, int task_length,
+ const char *callback, int callback_length) override;
+ void CreateFinish(const char *page_id) override;
+ int RefreshFinish(const char *page_id, const char *task,
+ const char *callback) override;
+ void UpdateAttrs(const char *page_id, const char *ref, const char *data,
+ int data_length) override;
+ void UpdateStyle(const char *page_id, const char *ref, const char *data,
+ int data_length) override;
+ void RemoveElement(const char *page_id, const char *ref) override;
+ void MoveElement(const char *page_id, const char *ref, const char *parent_ref,
+ int index) override;
+ void AddEvent(const char *page_id, const char *ref,
+ const char *event) override;
+ void RemoveEvent(const char *page_id, const char *ref,
+ const char *event) override;
+ const char *CallGCanvasLinkNative(const char *context_id, int type,
+ const char *arg) override;
+ int SetInterval(const char *page_id, const char *callback_id,
+ const char *time) override;
+ void ClearInterval(const char *page_id, const char *callback_id) override;
+ const char *CallT3DLinkNative(int type, const char *arg) override;
+ void PostMessage(const char *vim_id, const char *data, int dataLength) override;
+ void DispatchMessage(const char *client_id, const char *data, int dataLength,
+ const char *callback, const char *vm_id) override;
+ void ReportException(const char *page_id, const char *func,
+ const char *exception_string) override;
+ void SetJSVersion(const char *js_version) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CoreSideInSimple);
+};
+} // namespace js
+} // namespace bridge
+} // namespace weex
+
+#endif // WEEXV8_SIMPLE_CORE_SIDE_H
diff --git a/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_multi_process.cpp b/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_multi_process.cpp
new file mode 100644
index 0000000000..4e135f1bb5
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_multi_process.cpp
@@ -0,0 +1,480 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#include "android/jsengine/bridge/script/script_bridge_in_multi_process.h"
+
+#include "android/jsengine/bridge/script/core_side_in_multi_process.h"
+#include "android/jsengine/bridge/script/core_side_in_simple.h"
+#include "android/jsengine/bridge/script/script_side_in_simple.h"
+#include "android/jsengine/bridge/script/script_side_in_queue.h"
+#include "android/jsengine/object/weex_env.h"
+#include "android/jsengine/weex_ipc_server.h"
+#include "android/jsengine/weex_jsc_utils.h"
+#include "android/jsengine/weex_runtime.h"
+#include "third_party/IPC/IPCArguments.h"
+#include "third_party/IPC/IPCException.h"
+#include "third_party/IPC/IPCHandler.h"
+#include "third_party/IPC/IPCMessageJS.h"
+#include "third_party/IPC/IPCResult.h"
+#include "third_party/IPC/IPCString.h"
+
+static WeexJSServer *server = nullptr;
+
+static unsigned long parseUL(const char *s) {
+ unsigned long val;
+ errno = 0;
+ val = strtoul(s, nullptr, 10);
+ if (errno) {
+ LOGE("failed to parse ul: %s %s", s, strerror(errno));
+ _exit(1);
+ }
+ return val;
+}
+
+struct ThreadData {
+ int fd;
+ int fd_client;
+ bool enableTrace;
+ char* crashFileName;
+};
+
+static void *threadEntry(void *_td) {
+ ThreadData *td = static_cast<ThreadData *>(_td);
+ // server = new weex::IPCServer(static_cast<int>(td->fd),
+ // static_cast<bool>(td->enableTrace));
+ server = new WeexJSServer(static_cast<int>(td->fd), static_cast<int>(td->fd_client),
+ static_cast<bool>(td->enableTrace), td->crashFileName);
+ // Register handler for bridge
+ weex::bridge::js::ScriptBridgeInMultiProcess::RegisterIPCCallback(server->getHandler());
+ nice(6);
+ try {
+ server->loop();
+ } catch (IPCException &e) {
+ LOGE("%s", e.msg());
+ _exit(1);
+ }
+ return static_cast<void **>(nullptr);
+}
+
+extern "C" int serverMain(int argc, char **argv) {
+ unsigned long fd;
+ unsigned long fd_client = 0;
+ unsigned long enableTrace;
+ if (argc < 4) {
+ LOGE("argc is not correct");
+ _exit(1);
+ }
+ fd = parseUL(argv[1]);
+ fd_client = parseUL(argv[2]);
+ enableTrace = parseUL(argv[3]);
+ char* fileName = argv[4];
+ pthread_attr_t threadAttr;
+ pthread_attr_init(&threadAttr);
+ pthread_attr_setstacksize(&threadAttr, 10 * 1024 * 1024);
+ pthread_t thread;
+ ThreadData td = {static_cast<int>(fd), static_cast<int>(fd_client), static_cast<bool>(enableTrace),fileName};
+ pthread_create(&thread, &threadAttr, threadEntry, &td);
+ void *rdata;
+ pthread_join(thread, &rdata);
+ return 0;
+}
+
+namespace weex {
+ namespace bridge {
+ namespace js {
+
+ static inline const char* GetUTF8StringFromIPCArg(IPCArguments* arguments, size_t index) {
+ return arguments->getByteArray(index)->length == 0 ? nullptr : arguments->getByteArray(index)->content;
+ }
+
+ ScriptBridgeInMultiProcess *ScriptBridgeInMultiProcess::g_instance = NULL;
+
+ ScriptBridgeInMultiProcess::ScriptBridgeInMultiProcess() {
+ set_script_side(new ScriptSideInQueue());
+ set_core_side(new CoreSideInMultiProcess());
+ }
+
+ ScriptBridgeInMultiProcess::~ScriptBridgeInMultiProcess() {}
+
+ static void FillVectorOfValueWithType(std::vector<VALUE_WITH_TYPE *> ¶ms,
+ IPCArguments *arguments, size_t start,
+ size_t end) {
+ for (size_t i = start; i < end; ++i) {
+ auto value = new ValueWithType;
+ switch (arguments->getType(i)) {
+ case IPCType::DOUBLE: {
+ value->type = ParamsType::DOUBLE;
+ value->value.doubleValue = arguments->get<double>(i);
+ }
+ break;
+ case IPCType::STRING: {
+ const IPCString *ipcstr = arguments->getString(i);
+ size_t size = ipcstr->length * sizeof(uint16_t);
+ auto temp = (WeexString *) malloc(size + sizeof(WeexString));
+ memset(temp, 0, size + sizeof(WeexString));
+ temp->length = ipcstr->length;
+ memcpy(temp->content, ipcstr->content, size);
+ value->type = ParamsType::STRING;
+ value->value.string = temp;
+ }
+ break;
+ case IPCType::JSONSTRING: {
+ const IPCString *ipcstr = arguments->getString(i);
+ size_t size = ipcstr->length * sizeof(uint16_t);
+ auto temp = (WeexString *) malloc(size + sizeof(WeexString));
+ memset(temp, 0, size + sizeof(WeexString));
+ temp->length = ipcstr->length;
+ memcpy(temp->content, ipcstr->content, size);
+ value->type = ParamsType::JSONSTRING;
+ value->value.string = temp;
+ }
+ break;
+ case IPCType::BYTEARRAY: {
+ const IPCByteArray *array = arguments->getByteArray(i);
+ size_t size = array->length * sizeof(char);
+ auto temp = (WeexByteArray *) malloc(size + sizeof(WeexByteArray));
+ memset(temp, 0, size + sizeof(WeexByteArray));
+ temp->length = array->length;
+ memcpy(temp->content, array->content, size);
+ value->type = ParamsType::BYTEARRAY;
+ value->value.byteArray = temp;
+ }
+ break;
+ default: {
+ value->type = ParamsType::JSUNDEFINED;
+ }
+ break;
+ }
+ params.push_back(value);
+ }
+ }
+
+ static void ClearVectorOfValueWithType(std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ for (auto it = params.begin(); it != params.end(); ++it) {
+ switch ((*it)->type) {
+ case ParamsType::STRING:
+ case ParamsType::JSONSTRING:
+ free((*it)->value.string);
+ break;
+ case ParamsType::BYTEARRAY:
+ free((*it)->value.byteArray);
+ break;
+ default:
+ break;
+ }
+ delete *it;
+ }
+ }
+
+ void ScriptBridgeInMultiProcess::RegisterIPCCallback(IPCHandler *handler) {
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::INITFRAMEWORK),
+ InitFramework);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::INITAPPFRAMEWORK),
+ InitAppFramework);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::CREATEAPPCONTEXT),
+ CreateAppContext);
+ handler->registerHandler(
+ static_cast<uint32_t>(IPCJSMsg::EXECJSONAPPWITHRESULT),
+ ExecJSOnAppWithResult);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::CALLJSONAPPCONTEXT),
+ CallJSOnAppContext);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::DESTORYAPPCONTEXT),
+ DestroyAppContext);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::EXECJSSERVICE),
+ ExecJSService);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::TAKEHEAPSNAPSHOT),
+ TakeHeapSnapshot);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::EXECTIMERCALLBACK),
+ ExecTimerCallback);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::EXECJS), ExecJS);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::EXECJSWITHRESULT),
+ ExecJSWithResult);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::EXECJSWITHCALLBACK),
+ ExecJSWithCallback);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::CREATEINSTANCE),
+ CreateInstance);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::DESTORYINSTANCE),
+ DestroyInstance);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::EXECJSONINSTANCE),
+ ExecJSOnInstance);
+ handler->registerHandler(static_cast<uint32_t>(IPCJSMsg::UPDATEGLOBALCONFIG),
+ UpdateGlobalConfig);
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::InitFramework(
+ IPCArguments *arguments) {
+ //TODO change ScriptSide
+ LOGD("ScriptBridgeInMultiProcess::InitFramework");
+ static_cast<ScriptSideInQueue *>(Instance()->script_side())
+ ->setTaskQueue(new WeexTaskQueue());
+ WeexEnv::getEnv()->setScriptBridge(Instance());
+
+ // Source
+ const char *source = GetUTF8StringFromIPCArg(arguments, 0);
+ // Params
+ size_t startCount = 1;
+ size_t count = arguments->getCount();
+ std::vector<INIT_FRAMEWORK_PARAMS *> params;
+ for (size_t i = startCount; i < count; i += 2) {
+ if (arguments->getType(i) != IPCType::BYTEARRAY) {
+ continue;
+ }
+ if (arguments->getType(1 + i) != IPCType::BYTEARRAY) {
+ continue;
+ }
+ const IPCByteArray *ba = arguments->getByteArray(1 + i);
+ const IPCByteArray *ba_type = arguments->getByteArray(i);
+ auto init_framework_params =
+ (INIT_FRAMEWORK_PARAMS *) malloc(sizeof(INIT_FRAMEWORK_PARAMS));
+ if (init_framework_params == nullptr) {
+ break;
+ }
+ memset(init_framework_params, 0, sizeof(INIT_FRAMEWORK_PARAMS));
+ init_framework_params->type = IPCByteArrayToWeexByteArray(ba_type);
+ init_framework_params->value = IPCByteArrayToWeexByteArray(ba);
+ params.push_back(init_framework_params);
+ }
+ int val = Instance()->script_side()->InitFramework(source, params);
+ freeInitFrameworkParams(params);
+ return createInt32Result(val);
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::InitAppFramework(
+ IPCArguments *arguments) {
+ const char *id = GetUTF8StringFromIPCArg(arguments, 0);
+ const char *js = GetUTF8StringFromIPCArg(arguments, 1);
+ LOGD("Weex jsserver IPCJSMsg::INITAPPFRAMEWORK id:%s", id);
+ if (strcmp(id, "") == 0) {
+ return createInt32Result(static_cast<int32_t>(false));
+ }
+ // Params
+ size_t startCount = 2;
+ size_t count = arguments->getCount();
+ std::vector<INIT_FRAMEWORK_PARAMS *> params;
+ for (size_t i = startCount; i < count; i += 2) {
+ if (arguments->getType(i) != IPCType::BYTEARRAY) {
+ continue;
+ }
+ if (arguments->getType(1 + i) != IPCType::BYTEARRAY) {
+ continue;
+ }
+ const IPCByteArray *ba = arguments->getByteArray(1 + i);
+ const IPCByteArray *ba_type = arguments->getByteArray(i);
+ auto init_framework_params =
+ (INIT_FRAMEWORK_PARAMS *) malloc(sizeof(INIT_FRAMEWORK_PARAMS));
+ if (init_framework_params == nullptr) {
+ break;
+ }
+ memset(init_framework_params, 0, sizeof(INIT_FRAMEWORK_PARAMS));
+ init_framework_params->type = IPCByteArrayToWeexByteArray(ba_type);
+ init_framework_params->value = IPCByteArrayToWeexByteArray(ba);
+ params.push_back(init_framework_params);
+ }
+ return createInt32Result(
+ Instance()->script_side()->InitAppFramework(id, js, params));
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::CreateAppContext(
+ IPCArguments *arguments) {
+ const char *instanceID = GetUTF8StringFromIPCArg(arguments, 0);
+ const char *js = GetUTF8StringFromIPCArg(arguments, 1);
+ return createInt32Result(
+ Instance()->script_side()->CreateAppContext(instanceID, js));
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::ExecJSOnAppWithResult(
+ IPCArguments *arguments) {
+ LOGD("ScriptBridgeInMultiProcess::ExecJSONAppWithResult");
+ const char *instanceID = GetUTF8StringFromIPCArg(arguments, 0);
+ const char *js = GetUTF8StringFromIPCArg(arguments, 1);
+ const std::unique_ptr<WeexJSResult> &ptr = Instance()->script_side()->ExecJSOnAppWithResult(instanceID, js);
+
+ return createByteArrayResult(ptr->data.get(), ptr->length);
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::CallJSOnAppContext(
+ IPCArguments *arguments) {
+ LOGD("ScriptBridgeInMultiProcess::CallJSONAppContext");
+ const char *instanceId = GetUTF8StringFromIPCArg(arguments, 0);
+ const char *func = GetUTF8StringFromIPCArg(arguments, 1);
+
+ std::vector<VALUE_WITH_TYPE *> params;
+ FillVectorOfValueWithType(params, arguments, 2, arguments->getCount());
+ auto result =
+ Instance()->script_side()->CallJSOnAppContext(instanceId, func, params);
+ ClearVectorOfValueWithType(params);
+ return createInt32Result(result);
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::DestroyAppContext(
+ IPCArguments *arguments) {
+ LOGD("ScriptBridgeInMultiProcess::DestroyAppContext");
+ const char *instanceID = GetUTF8StringFromIPCArg(arguments, 0);
+ if (strlen(instanceID) == 0) {
+ return createInt32Result(static_cast<int32_t>(false));
+ }
+
+ return createInt32Result(
+ Instance()->script_side()->DestroyAppContext(instanceID));
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::ExecJSService(
+ IPCArguments *arguments) {
+ LOGD("ScriptBridgeInMultiProcess::ExecJSService");
+ const char *source = GetUTF8StringFromIPCArg(arguments, 0);
+ return createInt32Result(Instance()->script_side()->ExecJsService(source));
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::ExecTimerCallback(
+ IPCArguments *arguments) {
+ LOGD("ScriptBridgeInMultiProcess::ExecTimerCallback");
+ const char *source = GetUTF8StringFromIPCArg(arguments, 0);
+ Instance()->script_side()->ExecTimeCallback(source);
+ return createVoidResult();
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::ExecJS(
+ IPCArguments *arguments) {
+ LOGD("ScriptBridgeInMultiProcess::ExecJS");
+ const char *instanceId = GetUTF8StringFromIPCArg(arguments, 0);
+ const char *namespaceStr = GetUTF8StringFromIPCArg(arguments, 1);
+ const char *func = GetUTF8StringFromIPCArg(arguments, 2);
+
+ std::vector<VALUE_WITH_TYPE *> params;
+ FillVectorOfValueWithType(params, arguments, 3, arguments->getCount());
+ auto result =
+ Instance()->script_side()->ExecJS(instanceId, namespaceStr, func, params);
+ ClearVectorOfValueWithType(params);
+ return createInt32Result(result);
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::ExecJSWithResult(
+ IPCArguments *arguments) {
+ LOGD("ScriptBridgeInMultiProcess::ExecJSWithResult");
+ const char *instanceId = GetUTF8StringFromIPCArg(arguments, 0);
+ const char *namespaceStr = GetUTF8StringFromIPCArg(arguments, 1);
+ const char *func = GetUTF8StringFromIPCArg(arguments, 2);
+
+ std::vector<VALUE_WITH_TYPE *> params;
+ FillVectorOfValueWithType(params, arguments, 3, arguments->getCount());
+ const std::unique_ptr<WeexJSResult> &ptr = Instance()->script_side()->ExecJSWithResult(
+ instanceId, namespaceStr, func, params);
+ ClearVectorOfValueWithType(params);
+
+ return createByteArrayResult(ptr->data.get(), ptr->length);
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::ExecJSWithCallback(
+ IPCArguments *arguments) {
+ const char *instanceId = GetUTF8StringFromIPCArg(arguments, 0);
+ const char *namespaceStr = GetUTF8StringFromIPCArg(arguments, 1);
+ const char *func = GetUTF8StringFromIPCArg(arguments, 2);
+ // pass callback_id before params
+ long id = arguments->get<int64_t>(3);
+
+ std::vector<VALUE_WITH_TYPE *> params;
+ FillVectorOfValueWithType(params, arguments, 4, arguments->getCount());
+ Instance()->script_side()->ExecJSWithCallback(
+ instanceId, namespaceStr, func, params, id);
+ ClearVectorOfValueWithType(params);
+
+ return createVoidResult();
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::CreateInstance(
+ IPCArguments *arguments) {
+ LOGD("ScriptBridgeInMultiProcess::CreateInstance");
+
+ const char *instanceID = GetUTF8StringFromIPCArg(arguments, 0);
+ const char *func = GetUTF8StringFromIPCArg(arguments, 1);
+ const char *script = GetUTF8StringFromIPCArg(arguments, 2);
+ const char *opts = GetUTF8StringFromIPCArg(arguments, 3);
+ const char *initData = GetUTF8StringFromIPCArg(arguments, 4);
+ const char *extendsApi = GetUTF8StringFromIPCArg(arguments, 5);
+ size_t startCount = 6;
+ size_t count = arguments->getCount();
+ std::vector<INIT_FRAMEWORK_PARAMS*> params;
+ for (size_t i = startCount; i < count; i += 2) {
+ if (arguments->getType(i) != IPCType::BYTEARRAY) {
+ continue;
+ }
+ if (arguments->getType(1 + i) != IPCType::BYTEARRAY) {
+ continue;
+ }
+ const IPCByteArray* ba = arguments->getByteArray(1 + i);
+ const IPCByteArray* ba_type = arguments->getByteArray(i);
+ auto init_framework_params =
+ (INIT_FRAMEWORK_PARAMS*)malloc(sizeof(INIT_FRAMEWORK_PARAMS));
+ if (init_framework_params == nullptr) {
+ break;
+ }
+ memset(init_framework_params, 0, sizeof(INIT_FRAMEWORK_PARAMS));
+ init_framework_params->type = IPCByteArrayToWeexByteArray(ba_type);
+ init_framework_params->value = IPCByteArrayToWeexByteArray(ba);
+ params.push_back(init_framework_params);
+ }
+ auto result = createInt32Result(Instance()->script_side()->CreateInstance(
+ instanceID, func, script, opts, initData, extendsApi,params));
+ freeInitFrameworkParams(params);
+ return result;
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::DestroyInstance(
+ IPCArguments *arguments) {
+ LOGD("ScriptBridgeInMultiProcess::DestroyInstance");
+ const char *instanceID = GetUTF8StringFromIPCArg(arguments, 0);
+ if (strlen(instanceID) == 0) {
+ LOGE("DestoryInstance instanceId is NULL");
+ return createInt32Result(static_cast<int32_t>(false));
+ }
+
+ return createInt32Result(
+ Instance()->script_side()->DestroyInstance(instanceID));
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::ExecJSOnInstance(
+ IPCArguments *arguments) {
+ LOGD("ScriptBridgeInMultiProcess::ExecJSONInstance");
+ const char *instanceID = GetUTF8StringFromIPCArg(arguments, 0);
+ const char *script = GetUTF8StringFromIPCArg(arguments, 1);
+
+ const std::unique_ptr<WeexJSResult> &ptr = Instance()->script_side()->ExecJSOnInstance(instanceID, script);
+
+ return createByteArrayResult(ptr->data.get(), ptr->length);
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::UpdateGlobalConfig(
+ IPCArguments *arguments) {
+ LOGD("ScriptBridgeInMultiProcess::UpdateGlobalConfig");
+ const char *configString = GetUTF8StringFromIPCArg(arguments, 0);
+ Instance()->script_side()->UpdateGlobalConfig(configString);
+ return createVoidResult();
+ }
+
+ std::unique_ptr<IPCResult> ScriptBridgeInMultiProcess::TakeHeapSnapshot(
+ IPCArguments *arguments) {
+ return createVoidResult();
+ }
+
+ } // namespace js
+ } // namespace bridge
+} // namespace weex
diff --git a/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_multi_process.h b/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_multi_process.h
new file mode 100644
index 0000000000..f519b867fd
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_multi_process.h
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#ifndef WEEXV8_JS_MULTI_PROCESS_BRIDGE_H
+#define WEEXV8_JS_MULTI_PROCESS_BRIDGE_H
+
+#include "core/bridge/script_bridge.h"
+
+class IPCHandler;
+class IPCResult;
+class IPCArguments;
+
+namespace weex {
+namespace bridge {
+namespace js {
+class ScriptBridgeInMultiProcess : public WeexCore::ScriptBridge {
+ public:
+ static ScriptBridgeInMultiProcess* Instance() {
+ if (g_instance == NULL) {
+ g_instance = new ScriptBridgeInMultiProcess();
+ }
+ return g_instance;
+ }
+
+ ScriptBridgeInMultiProcess();
+ virtual ~ScriptBridgeInMultiProcess();
+ static void RegisterIPCCallback(IPCHandler* handler);
+
+ private:
+#define IPC_METHOD(method_name) \
+ static std::unique_ptr<IPCResult> method_name(IPCArguments* arguments);
+
+ IPC_METHOD(InitFramework)
+ IPC_METHOD(InitAppFramework)
+ IPC_METHOD(CreateAppContext)
+ IPC_METHOD(ExecJSOnAppWithResult)
+ IPC_METHOD(CallJSOnAppContext)
+ IPC_METHOD(DestroyAppContext)
+ IPC_METHOD(ExecTimerCallback)
+ IPC_METHOD(ExecJSService)
+ IPC_METHOD(TakeHeapSnapshot)
+ IPC_METHOD(ExecJS)
+ IPC_METHOD(ExecJSWithResult)
+ IPC_METHOD(ExecJSWithCallback)
+ IPC_METHOD(CreateInstance)
+ IPC_METHOD(DestroyInstance)
+ IPC_METHOD(ExecJSOnInstance)
+ IPC_METHOD(UpdateGlobalConfig)
+
+ private:
+ static ScriptBridgeInMultiProcess* g_instance;
+ DISALLOW_COPY_AND_ASSIGN(ScriptBridgeInMultiProcess);
+};
+} // namespace js
+} // namespace bridge
+} // namespace weex
+
+#endif // WEEXV8_JS_MULTI_PROCESS_BRIDGE_H
diff --git a/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_multi_so.cpp b/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_multi_so.cpp
new file mode 100644
index 0000000000..bcdf3faf1a
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_multi_so.cpp
@@ -0,0 +1,157 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#include "android/jsengine/bridge/script/script_bridge_in_multi_so.h"
+
+#include "android/jsengine/bridge/platform/platform_bridge_in_multi_so.h"
+#include "android/jsengine/bridge/script/core_side_in_multi_process.h"
+#include "android/jsengine/bridge/script/core_side_in_multi_so.h"
+#include "android/jsengine/bridge/script/core_side_in_simple.h"
+#include "android/jsengine/bridge/script/script_side_in_simple.h"
+#include "android/jsengine/bridge/script/script_side_in_queue.h"
+#include "android/jsengine/object/weex_env.h"
+#include "android/jsengine/weex_runtime.h"
+#include "core/manager/weex_core_manager.h"
+
+static FunctionsExposedByCore *g_functions_exposed_by_core = nullptr;
+
+extern "C" FunctionsExposedByJS *ExchangeJSBridgeFunctions(
+ FunctionsExposedByCore *functions) {
+ g_functions_exposed_by_core = functions;
+ return weex::bridge::js::ScriptBridgeInMultiSo::GetExposedFunctions();
+}
+
+namespace weex {
+namespace bridge {
+namespace js {
+ScriptBridgeInMultiSo *ScriptBridgeInMultiSo::g_instance = NULL;
+
+ScriptBridgeInMultiSo::ScriptBridgeInMultiSo() {
+ set_script_side(new ScriptSideInQueue());
+// set_core_side(new CoreSideInSimple());
+ set_core_side(new CoreSideInMultiSo(g_functions_exposed_by_core));
+ // set_core_side(new MultiProcessCoreSide());
+}
+
+ScriptBridgeInMultiSo::~ScriptBridgeInMultiSo() {}
+
+FunctionsExposedByJS *ScriptBridgeInMultiSo::GetExposedFunctions() {
+ FunctionsExposedByJS temp = {
+ InitFramework, InitAppFramework, CreateAppContext,
+ ExecJSOnAppWithResult, CallJSOnAppContext, DestroyAppContext,
+ ExecJSService, ExecTimeCallback, ExecJS,
+ ExecJSWithResult, ExecJSWithCallback, CreateInstance, ExecJSOnInstance,
+ DestroyInstance, UpdateGlobalConfig};
+ auto functions = (FunctionsExposedByJS *)malloc(sizeof(FunctionsExposedByJS));
+ memset(functions, 0, sizeof(FunctionsExposedByJS));
+ memcpy(functions, &temp, sizeof(FunctionsExposedByJS));
+ return functions;
+}
+
+int ScriptBridgeInMultiSo::InitFramework(
+ const char *script, std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) {
+ static_cast<ScriptSideInQueue *>(Instance()->script_side())
+ ->setTaskQueue(new WeexTaskQueue(false));
+
+ WeexEnv::getEnv()->setScriptBridge(Instance());
+
+ return Instance()->script_side()->InitFramework(script, params);
+}
+
+int ScriptBridgeInMultiSo::InitAppFramework(
+ const char *instanceId, const char *appFramework,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) {
+ return Instance()->script_side()->InitAppFramework(instanceId, appFramework,
+ params);
+}
+
+int ScriptBridgeInMultiSo::CreateAppContext(const char *instanceId,
+ const char *jsBundle) {
+ return Instance()->script_side()->CreateAppContext(instanceId, jsBundle);
+}
+
+std::unique_ptr<WeexJSResult> ScriptBridgeInMultiSo::ExecJSOnAppWithResult(const char *instanceId,
+ const char *jsBundle) {
+ return Instance()->script_side()->ExecJSOnAppWithResult(instanceId, jsBundle);
+}
+
+int ScriptBridgeInMultiSo::CallJSOnAppContext(
+ const char *instanceId, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ return Instance()->script_side()->CallJSOnAppContext(instanceId, func, params);
+}
+
+int ScriptBridgeInMultiSo::DestroyAppContext(const char *instanceId) {
+ return Instance()->script_side()->DestroyAppContext(instanceId);
+}
+
+int ScriptBridgeInMultiSo::ExecJSService(const char *source) {
+ return Instance()->script_side()->ExecJsService(source);
+}
+
+int ScriptBridgeInMultiSo::ExecTimeCallback(const char *source) {
+ return Instance()->script_side()->ExecTimeCallback(source);
+}
+
+int ScriptBridgeInMultiSo::ExecJS(const char *instanceId, const char *nameSpace,
+ const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ return Instance()->script_side()->ExecJS(instanceId, nameSpace, func, params);
+}
+
+std::unique_ptr<WeexJSResult> ScriptBridgeInMultiSo::ExecJSWithResult(
+ const char *instanceId, const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ return Instance()->script_side()->ExecJSWithResult(instanceId, nameSpace, func,
+ params);
+}
+
+void ScriptBridgeInMultiSo::ExecJSWithCallback(
+ const char *instanceId, const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms, long callback_id) {
+ Instance()->script_side()->ExecJSWithCallback(instanceId, nameSpace, func, params, callback_id);
+}
+
+int ScriptBridgeInMultiSo::CreateInstance(const char *instanceId,
+ const char *func, const char *script,
+ const char *opts,
+ const char *initData,
+ const char *extendsApi, std::vector<INIT_FRAMEWORK_PARAMS*>& params) {
+ return Instance()->script_side()->CreateInstance(instanceId, func, script, opts,
+ initData, extendsApi, params);
+}
+
+std::unique_ptr<WeexJSResult> ScriptBridgeInMultiSo::ExecJSOnInstance(const char *instanceId,
+ const char *script) {
+ return Instance()->script_side()->ExecJSOnInstance(instanceId, script);
+}
+
+int ScriptBridgeInMultiSo::DestroyInstance(const char *instanceId) {
+ return Instance()->script_side()->DestroyInstance(instanceId);
+}
+
+int ScriptBridgeInMultiSo::UpdateGlobalConfig(const char *config) {
+ return Instance()->script_side()->UpdateGlobalConfig(config);
+}
+} // namespace js
+} // namespace bridge
+} // namespace weex
diff --git a/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_multi_so.h b/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_multi_so.h
new file mode 100644
index 0000000000..2a06c5747e
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_multi_so.h
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#ifndef WEEXV8_MULTI_SO_JS_BRIDGE_H
+#define WEEXV8_MULTI_SO_JS_BRIDGE_H
+
+#include "core/bridge/script_bridge.h"
+
+namespace weex {
+namespace bridge {
+namespace js {
+class ScriptBridgeInMultiSo : public WeexCore::ScriptBridge {
+ public:
+ static FunctionsExposedByJS *GetExposedFunctions();
+
+ static int InitFramework(const char *script,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms);
+
+ static int InitAppFramework(const char *instanceId, const char *appFramework,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms);
+
+ static int CreateAppContext(const char *instanceId, const char *jsBundle);
+
+ static std::unique_ptr<WeexJSResult> ExecJSOnAppWithResult(const char *instanceId,
+ const char *jsBundle);
+
+ static int CallJSOnAppContext(const char *instanceId, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms);
+
+ static int DestroyAppContext(const char *instanceId);
+
+ static int ExecJSService(const char *source);
+
+ static int ExecTimeCallback(const char *source);
+
+ static int ExecJS(const char *instanceId, const char *nameSpace,
+ const char *func, std::vector<VALUE_WITH_TYPE *> ¶ms);
+
+ static std::unique_ptr<WeexJSResult> ExecJSWithResult(const char *instanceId,
+ const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms);
+
+ static void ExecJSWithCallback(const char *instanceId,
+ const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms, long callback_id);
+
+
+ static int CreateInstance(const char *instanceId, const char *func,
+ const char *script, const char *opts,
+ const char *initData, const char *extendsApi, std::vector<INIT_FRAMEWORK_PARAMS*>& params);
+
+ static std::unique_ptr<WeexJSResult> ExecJSOnInstance(const char *instanceId, const char *script);
+
+ static int DestroyInstance(const char *instanceId);
+
+ static int UpdateGlobalConfig(const char *config);
+
+ private:
+ static ScriptBridgeInMultiSo *g_instance;
+ static ScriptBridgeInMultiSo *Instance() {
+ if (g_instance == NULL) {
+ g_instance = new ScriptBridgeInMultiSo();
+ }
+ return g_instance;
+ }
+
+ ScriptBridgeInMultiSo();
+ virtual ~ScriptBridgeInMultiSo();
+ DISALLOW_COPY_AND_ASSIGN(ScriptBridgeInMultiSo);
+};
+} // namespace js
+} // namespace bridge
+} // namespace weex
+
+#endif // WEEXV8_MULTI_SO_JS_BRIDGE_H
diff --git a/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_simple.cpp b/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_simple.cpp
new file mode 100644
index 0000000000..e714220ddf
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_simple.cpp
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/29.
+//
+
+#include "android/jsengine/bridge/script/script_bridge_in_simple.h"
+
+#include "android/jsengine/object/weex_env.h"
+#include "android/jsengine/bridge/script/core_side_in_simple.h"
+#include "android/jsengine/bridge/script/script_side_in_simple.h"
+#include "android/jsengine/bridge/script/script_side_in_queue.h"
+#include "android/jsengine/weex_runtime.h"
+
+namespace weex {
+namespace bridge {
+namespace js {
+ScriptBridgeInSimple* ScriptBridgeInSimple::g_instance = NULL;
+
+ScriptBridgeInSimple::ScriptBridgeInSimple() {
+ WeexEnv::getEnv()->setScriptBridge(this);
+ set_script_side(new ScriptSideInSimple(new WeexRuntime(this, false)));
+ set_core_side(new CoreSideInSimple());
+}
+
+ScriptBridgeInSimple::~ScriptBridgeInSimple() {}
+} // namespace js
+} // namespace bridge
+} // namespace weex
diff --git a/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_simple.h b/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_simple.h
new file mode 100644
index 0000000000..8554d45c02
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/script_bridge_in_simple.h
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/29.
+//
+
+#ifndef WEEXV8_SCRIPT_BRIDGE_IN_SIMPLE_H
+#define WEEXV8_SCRIPT_BRIDGE_IN_SIMPLE_H
+
+#include "core/bridge/script_bridge.h"
+
+namespace weex {
+namespace bridge {
+namespace js {
+class ScriptBridgeInSimple : public WeexCore::ScriptBridge {
+ public:
+ static ScriptBridgeInSimple *Instance() {
+ if (g_instance == NULL) {
+ g_instance = new ScriptBridgeInSimple();
+ }
+ return g_instance;
+ }
+
+ private:
+ static ScriptBridgeInSimple *g_instance;
+ ScriptBridgeInSimple();
+ virtual ~ScriptBridgeInSimple();
+ DISALLOW_COPY_AND_ASSIGN(ScriptBridgeInSimple);
+};
+} // namespace js
+} // namespace bridge
+} // namespace weex
+
+#endif // WEEXV8_SCRIPT_BRIDGE_IN_SIMPLE_H
diff --git a/weex_core/Source/android/jsengine/bridge/script/script_side_in_queue.cpp b/weex_core/Source/android/jsengine/bridge/script/script_side_in_queue.cpp
new file mode 100644
index 0000000000..a4bfe665da
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/script_side_in_queue.cpp
@@ -0,0 +1,219 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by Darin on 2018/7/22.
+//
+
+#include "script_side_in_queue.h"
+
+#include "android/jsengine/task/impl/init_framework_task.h"
+#include "android/jsengine/task/impl/create_app_context_task.h"
+#include "android/jsengine/task/impl/create_instance_task.h"
+#include "android/jsengine/task/impl/call_js_on_app_context_task.h"
+#include "android/jsengine/task/impl/destory_app_context_task.h"
+#include "android/jsengine/task/impl/destory_instance_task.h"
+#include "android/jsengine/task/impl/exe_js_on_app_with_result.h"
+#include "android/jsengine/task/impl/update_global_config_task.h"
+#include "android/jsengine/task/impl/ctime_callback_task.h"
+#include "android/jsengine/task/impl/exe_js_services_task.h"
+#include "android/jsengine/task/impl/exe_js_on_instance_task.h"
+#include "android/jsengine/task/impl/exe_js_task.h"
+#include "android/jsengine/task/impl/take_heap_snapshot.h"
+#include "android/jsengine/task/impl/native_timer_task.h"
+
+namespace weex {
+ namespace bridge {
+ namespace js {
+ int ScriptSideInQueue::InitFramework(
+ const char *script, std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) {
+ LOGD("ScriptSideInQueue::InitFramework");
+// return runtime_->initFramework(String::fromUTF8(script), params);
+ weexTaskQueue_->addTask(new InitFrameworkTask(String::fromUTF8(script), params));
+ weexTaskQueue_->init();
+ return 1;
+ }
+
+ int ScriptSideInQueue::InitAppFramework(
+ const char *instanceId, const char *appFramework,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) {
+ LOGD("ScriptSideInQueue::InitAppFramework");
+ weexTaskQueue_->addTask(new InitFrameworkTask(String::fromUTF8(instanceId),
+ String::fromUTF8(appFramework), params));
+ return 1;
+
+// return runtime_->initAppFramework(String::fromUTF8(instanceId),
+// String::fromUTF8(appFramework), params);
+ }
+
+ int ScriptSideInQueue::CreateAppContext(const char *instanceId,
+ const char *jsBundle) {
+ LOGD("ScriptSideInQueue::CreateAppContext");
+ auto script = String::fromUTF8(jsBundle);
+ if(script.isEmpty()) {
+ return 0;
+ }
+ weexTaskQueue_->addTask(new CreateAppContextTask(String::fromUTF8(instanceId),
+ script));
+ return 1;
+ }
+
+ std::unique_ptr<WeexJSResult> ScriptSideInQueue::ExecJSOnAppWithResult(const char *instanceId,
+ const char *jsBundle) {
+ LOGD("ScriptSideInQueue::ExecJSOnAppWithResult");
+
+ WeexTask *task = new ExeJsOnAppWithResultTask(String::fromUTF8(instanceId),
+ String::fromUTF8(jsBundle));
+
+ auto future = std::unique_ptr<WeexTask::Future>(new WeexTask::Future());
+ task->set_future(future.get());
+
+ weexTaskQueue_->addTask(task);
+
+ return std::move(future->waitResult());
+ }
+
+ int ScriptSideInQueue::CallJSOnAppContext(
+ const char *instanceId, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ LOGD("ScriptSideInQueue::CallJSOnAppContext");
+
+ weexTaskQueue_->addTask(new CallJsOnAppContextTask(String::fromUTF8(instanceId),
+ String::fromUTF8(func), params));
+
+ return 1;
+ }
+
+ int ScriptSideInQueue::DestroyAppContext(const char *instanceId) {
+ LOGD("ScriptSideInQueue::DestroyAppContext");
+
+ weexTaskQueue_->addTask(new DestoryAppContextTask(String::fromUTF8(instanceId)));
+
+ return 1;
+ }
+
+ int ScriptSideInQueue::ExecJsService(const char *source) {
+ LOGD("ScriptSideInQueue::ExecJsService");
+
+ weexTaskQueue_->addTask(new ExeJsServicesTask(String::fromUTF8(source)));
+
+ return 1;
+ }
+
+ int ScriptSideInQueue::ExecTimeCallback(const char *source) {
+ LOGD("ScriptSideInQueue::ExecTimeCallback");
+
+ weexTaskQueue_->addTask(new CTimeCallBackTask(String::fromUTF8(source)));
+
+ return 1;
+ }
+
+ int ScriptSideInQueue::ExecJS(const char *instanceId, const char *nameSpace,
+ const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ LOGD("ScriptSideInQueue::ExecJS");
+
+ ExeJsTask *task = new ExeJsTask(instanceId, params);
+
+ task->addExtraArg(String::fromUTF8(nameSpace));
+ task->addExtraArg(String::fromUTF8(func));
+
+ weexTaskQueue_->addTask(task);
+
+ return 1;
+ }
+
+ std::unique_ptr<WeexJSResult> ScriptSideInQueue::ExecJSWithResult(
+ const char *instanceId, const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ LOGD("ScriptSideInQueue::ExecJSWithResult");
+
+ ExeJsTask *task = new ExeJsTask(instanceId, params, true);
+
+ auto future = std::unique_ptr<WeexTask::Future>(new WeexTask::Future());
+ task->set_future(future.get());
+
+ task->addExtraArg(String::fromUTF8(nameSpace));
+ task->addExtraArg(String::fromUTF8(func));
+ weexTaskQueue_->addTask(task);
+ return std::move(future->waitResult());
+ }
+
+ void ScriptSideInQueue::ExecJSWithCallback(
+ const char *instanceId, const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms, long callback_id) {
+ LOGD("ScriptSideInQueue::ExecJSWithCallback");
+
+ ExeJsTask *task = new ExeJsTask(instanceId, params, callback_id);
+
+ task->addExtraArg(String::fromUTF8(nameSpace));
+ task->addExtraArg(String::fromUTF8(func));
+ weexTaskQueue_->addTask(task);
+ }
+
+ int ScriptSideInQueue::CreateInstance(const char *instanceId, const char *func,
+ const char *script, const char *opts,
+ const char *initData,
+ const char *extendsApi, std::vector<INIT_FRAMEWORK_PARAMS*>& params) {
+ LOGD(
+ "CreateInstance id = %s, func = %s, script = %s, opts = %s, initData = "
+ "%s, extendsApi = %s",
+ instanceId, func, script, opts, initData, extendsApi);
+
+ auto string = String::fromUTF8(script);
+ if(string.isEmpty()) {
+ return 0;
+ }
+ CreateInstanceTask *task = new CreateInstanceTask(String::fromUTF8(instanceId),
+ string, params);
+
+ task->addExtraArg(String::fromUTF8(func));
+ task->addExtraArg(String::fromUTF8(opts));
+ task->addExtraArg(String::fromUTF8(initData));
+ task->addExtraArg(String::fromUTF8(extendsApi));
+ weexTaskQueue_->addTask(task);
+
+ return 1;
+ }
+
+ std::unique_ptr<WeexJSResult> ScriptSideInQueue::ExecJSOnInstance(const char *instanceId,
+ const char *script) {
+ LOGD("ScriptSideInQueue::ExecJSOnInstance");
+ ExeJsOnInstanceTask *task = new ExeJsOnInstanceTask(String::fromUTF8(instanceId),
+ String::fromUTF8(script));
+ weexTaskQueue_->addTask(task);
+ auto future = std::unique_ptr<WeexTask::Future>(new WeexTask::Future());
+ task->set_future(future.get());
+ return std::move(future->waitResult());
+ }
+
+ int ScriptSideInQueue::DestroyInstance(const char *instanceId) {
+ LOGD("ScriptSideInQueue::DestroyInstance instanceId: %s \n", instanceId);
+ weexTaskQueue_->addTask(new DestoryInstanceTask(String::fromUTF8(instanceId)));
+ return 1;
+ }
+
+ int ScriptSideInQueue::UpdateGlobalConfig(const char *config) {
+ LOGD("ScriptSideInQueue::UpdateGlobalConfig");
+ weexTaskQueue_->addTask(new UpdateGlobalConfigTask(String::fromUTF8(config)));
+ return 1;
+ }
+ } // namespace js
+ } // namespace bridge
+
+} // namespace weex
diff --git a/weex_core/Source/android/jsengine/bridge/script/script_side_in_queue.h b/weex_core/Source/android/jsengine/bridge/script/script_side_in_queue.h
new file mode 100644
index 0000000000..39c65eb2f2
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/script_side_in_queue.h
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by Darin on 2018/7/22.
+//
+
+#ifndef WEEXV8_SCRIPT_SIDE_IN_QUEUE_H
+#define WEEXV8_SCRIPT_SIDE_IN_QUEUE_H
+
+#include "core/bridge/script_bridge.h"
+#include "android/jsengine/task/weex_task_queue.h"
+
+namespace weex {
+ namespace bridge {
+ namespace js {
+ class ScriptSideInQueue : public WeexCore::ScriptBridge::ScriptSide {
+
+ private:
+ WeexTaskQueue *weexTaskQueue_;
+
+ public:
+ explicit ScriptSideInQueue() : weexTaskQueue_(nullptr) {};
+
+ explicit ScriptSideInQueue(WeexTaskQueue *taskQueue) { weexTaskQueue_ = taskQueue; }
+
+ public:
+
+ void setTaskQueue(WeexTaskQueue *taskQueue) { weexTaskQueue_ = taskQueue; }
+
+ int InitFramework(const char *script,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) override;
+
+ int InitAppFramework(const char *instanceId, const char *appFramework,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) override;
+
+ int CreateAppContext(const char *instanceId, const char *jsBundle) override;
+
+ std::unique_ptr<WeexJSResult> ExecJSOnAppWithResult(const char *instanceId,
+ const char *jsBundle) override;
+
+ int CallJSOnAppContext(const char *instanceId, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) override;
+
+ int DestroyAppContext(const char *instanceId) override;
+
+ int ExecJsService(const char *source) override;
+
+ int ExecTimeCallback(const char *source) override;
+
+ int ExecJS(const char *instanceId, const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) override;
+
+ std::unique_ptr<WeexJSResult> ExecJSWithResult(const char *instanceId, const char *nameSpace,
+ const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) override;
+ void ExecJSWithCallback(const char *instanceId, const char *nameSpace,
+ const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms, long callback_id) override;
+
+
+ int CreateInstance(const char *instanceId, const char *func,
+ const char *script, const char *opts, const char *initData,
+ const char *extendsApi, std::vector<INIT_FRAMEWORK_PARAMS*>& params) override;
+
+ std::unique_ptr<WeexJSResult> ExecJSOnInstance(const char *instanceId, const char *script) override;
+
+ int DestroyInstance(const char *instanceId) override;
+
+ int UpdateGlobalConfig(const char *config) override;
+
+ };
+ } // namespace js
+ } // namespace bridge
+
+} // namespace weex
+
+
+#endif //WEEXV8_SCRIPT_SIDE_IN_QUEUE_H
diff --git a/weex_core/Source/android/jsengine/bridge/script/script_side_in_simple.cpp b/weex_core/Source/android/jsengine/bridge/script/script_side_in_simple.cpp
new file mode 100644
index 0000000000..9817601c84
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/script_side_in_simple.cpp
@@ -0,0 +1,141 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#include "script_side_in_simple.h"
+#include "android/jsengine/weex_runtime.h"
+
+namespace weex {
+namespace bridge {
+namespace js {
+int ScriptSideInSimple::InitFramework(
+ const char *script, std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) {
+ LOGD("ScriptSideInSimple::InitFramework");
+
+ return runtime_->initFramework(String::fromUTF8(script), params);
+}
+
+int ScriptSideInSimple::InitAppFramework(
+ const char *instanceId, const char *appFramework,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) {
+ LOGD("ScriptSideInSimple::InitAppFramework");
+ return runtime_->initAppFramework(String::fromUTF8(instanceId),
+ String::fromUTF8(appFramework), params);
+}
+
+int ScriptSideInSimple::CreateAppContext(const char *instanceId,
+ const char *jsBundle) {
+ LOGD("ScriptSideInSimple::CreateAppContext");
+ return runtime_->createAppContext(String::fromUTF8(instanceId),
+ String::fromUTF8(jsBundle));
+}
+
+std::unique_ptr<WeexJSResult> ScriptSideInSimple::ExecJSOnAppWithResult(const char *instanceId,
+ const char *jsBundle) {
+ LOGD("ScriptSideInSimple::ExecJSOnAppWithResult");
+ return runtime_->exeJSOnAppWithResult(String::fromUTF8(instanceId),
+ String::fromUTF8(jsBundle));
+}
+
+int ScriptSideInSimple::CallJSOnAppContext(
+ const char *instanceId, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ LOGD("ScriptSideInSimple::CallJSOnAppContext");
+ return runtime_->callJSOnAppContext(String::fromUTF8(instanceId),
+ String::fromUTF8(func), params);
+}
+
+int ScriptSideInSimple::DestroyAppContext(const char *instanceId) {
+ LOGD("ScriptSideInSimple::DestroyAppContext");
+ return runtime_->destroyAppContext(String::fromUTF8(instanceId));
+}
+
+int ScriptSideInSimple::ExecJsService(const char *source) {
+ LOGD("ScriptSideInSimple::ExecJsService");
+ return runtime_->exeJsService(String::fromUTF8(source));
+}
+
+int ScriptSideInSimple::ExecTimeCallback(const char *source) {
+ LOGD("ScriptSideInSimple::ExecTimeCallback");
+ return runtime_->exeCTimeCallback(String::fromUTF8(source));
+}
+
+int ScriptSideInSimple::ExecJS(const char *instanceId, const char *nameSpace,
+ const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ LOGD("ScriptSideInSimple::ExecJS");
+ return runtime_->exeJS(String::fromUTF8(instanceId),
+ String::fromUTF8(nameSpace), String::fromUTF8(func),
+ params);
+}
+
+std::unique_ptr<WeexJSResult> ScriptSideInSimple::ExecJSWithResult(
+ const char *instanceId, const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) {
+ LOGD("ScriptSideInSimple::ExecJSWithResult");
+ return runtime_->exeJSWithResult(String::fromUTF8(instanceId),
+ String::fromUTF8(nameSpace),
+ String::fromUTF8(func), params);
+}
+
+void ScriptSideInSimple::ExecJSWithCallback(
+ const char *instanceId, const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms, long callback_id) {
+ LOGD("ScriptSideInSimple::ExecJSWithResult");
+ runtime_->exeJSWithResult(String::fromUTF8(instanceId),
+ String::fromUTF8(nameSpace),
+ String::fromUTF8(func), params);
+}
+
+int ScriptSideInSimple::CreateInstance(const char *instanceId, const char *func,
+ const char *script, const char *opts,
+ const char *initData,
+ const char *extendsApi, std::vector<INIT_FRAMEWORK_PARAMS*>& params) {
+ LOGD(
+ "CreateInstance id = %s, func = %s, script = %s, opts = %s, initData = "
+ "%s, extendsApi = %s",
+ instanceId, func, script, opts, initData, extendsApi);
+
+ return runtime_->createInstance(
+ String::fromUTF8(instanceId), String::fromUTF8(func),
+ String::fromUTF8(script), String::fromUTF8(opts),
+ String::fromUTF8(initData), String::fromUTF8(extendsApi),params);
+}
+
+std::unique_ptr<WeexJSResult> ScriptSideInSimple::ExecJSOnInstance(const char *instanceId,
+ const char *script) {
+ LOGD("ScriptSideInSimple::ExecJSOnInstance");
+ return runtime_->exeJSOnInstance(String::fromUTF8(instanceId),
+ String::fromUTF8(script));
+}
+
+int ScriptSideInSimple::DestroyInstance(const char *instanceId) {
+ LOGD("ScriptSideInSimple::DestroyInstance");
+ return runtime_->destroyInstance(String::fromUTF8(instanceId));
+}
+
+int ScriptSideInSimple::UpdateGlobalConfig(const char *config) {
+ LOGD("ScriptSideInSimple::UpdateGlobalConfig");
+ return runtime_->updateGlobalConfig(String::fromUTF8(config));
+}
+} // namespace js
+} // namespace bridge
+} // namespace weex
diff --git a/weex_core/Source/android/jsengine/bridge/script/script_side_in_simple.h b/weex_core/Source/android/jsengine/bridge/script/script_side_in_simple.h
new file mode 100644
index 0000000000..f8cb02687a
--- /dev/null
+++ b/weex_core/Source/android/jsengine/bridge/script/script_side_in_simple.h
@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//
+// Created by yxp on 2018/6/15.
+//
+
+#ifndef WEEXV8_SIMPLE_JS_SIDE_H
+#define WEEXV8_SIMPLE_JS_SIDE_H
+
+#include "core/bridge/script_bridge.h"
+
+class WeexRuntime;
+
+namespace weex {
+namespace bridge {
+namespace js {
+class ScriptSideInSimple : public WeexCore::ScriptBridge::ScriptSide {
+ public:
+ int InitFramework(const char *script,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) override;
+
+ int InitAppFramework(const char *instanceId, const char *appFramework,
+ std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) override;
+
+ int CreateAppContext(const char *instanceId, const char *jsBundle) override;
+
+ std::unique_ptr<WeexJSResult> ExecJSOnAppWithResult(const char *instanceId,
+ const char *jsBundle) override;
+
+ int CallJSOnAppContext(const char *instanceId, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) override;
+
+ int DestroyAppContext(const char *instanceId) override;
+
+ int ExecJsService(const char *source) override;
+
+ int ExecTimeCallback(const char *source) override;
+
+ int ExecJS(const char *instanceId, const char *nameSpace, const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) override;
+
+ std::unique_ptr<WeexJSResult> ExecJSWithResult(const char *instanceId, const char *nameSpace,
+ const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms) override;
+
+ void ExecJSWithCallback(const char *instanceId, const char *nameSpace,
+ const char *func,
+ std::vector<VALUE_WITH_TYPE *> ¶ms, long callback_id) override;
+
+ int CreateInstance(const char *instanceId, const char *func,
+ const char *script, const char *opts, const char *initData,
+ const char *extendsApi, std::vector<INIT_FRAMEWORK_PARAMS*>& params) override;
+
+ std::unique_ptr<WeexJSResult> ExecJSOnInstance(const char *instanceId, const char *script) override;
+
+ int DestroyInstance(const char *instanceId) override;
+
+ int UpdateGlobalConfig(const char *config) override;
+
+ inline void set_runtime(WeexRuntime *runtime) { runtime_ = runtime; }
+
+ ScriptSideInSimple() : runtime_(nullptr) {}
+ ScriptSideInSimple(WeexRuntime *runtime) : runtime_(runtime) {}
+
+ virtual ~ScriptSideInSimple() {}
+
+ private:
+ WeexRuntime *runtime_;
+ DISALLOW_COPY_AND_ASSIGN(ScriptSideInSimple);
+};
+} // namespace js
+} // namespace bridge
+
+} // namespace weex
+
+#endif // WEEXV8_SIMPLE_JS_SIDE_H
diff --git a/weex_core/Source/android/jsengine/dependence/OptionsCommon.cmake b/weex_core/Source/android/jsengine/dependence/OptionsCommon.cmake
new file mode 100644
index 0000000000..0a4af71541
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/OptionsCommon.cmake
@@ -0,0 +1,277 @@
+add_definitions(-DBUILDING_WITH_CMAKE=1)
+
+# CODE_GENERATOR_PREPROCESSOR_WITH_LINEMARKERS only matters with GCC >= 4.7.0. Since this
+# version, -P does not output empty lines, which currently breaks make_names.pl in
+# WebCore. Investigating whether make_names.pl should be changed instead is left as an exercise to
+# the reader.
+if (MSVC)
+ # FIXME: Some codegenerators don't support paths with spaces. So use the executable name only.
+ get_filename_component(CODE_GENERATOR_PREPROCESSOR_EXECUTABLE ${CMAKE_CXX_COMPILER} ABSOLUTE)
+
+ set(CODE_GENERATOR_PREPROCESSOR_ARGUMENTS "/nologo /EP")
+ set(CODE_GENERATOR_PREPROCESSOR "\"${CODE_GENERATOR_PREPROCESSOR_EXECUTABLE}\" ${CODE_GENERATOR_PREPROCESSOR_ARGUMENTS}")
+
+ set(CODE_GENERATOR_PREPROCESSOR_WITH_LINEMARKERS ${CODE_GENERATOR_PREPROCESSOR})
+else ()
+ set(CODE_GENERATOR_PREPROCESSOR_EXECUTABLE ${CMAKE_CXX_COMPILER})
+
+ set(CODE_GENERATOR_PREPROCESSOR_ARGUMENTS "-E -P -x c++")
+ set(CODE_GENERATOR_PREPROCESSOR "${CODE_GENERATOR_PREPROCESSOR_EXECUTABLE} ${CODE_GENERATOR_PREPROCESSOR_ARGUMENTS}")
+
+ set(CODE_GENERATOR_PREPROCESSOR_WITH_LINEMARKERS_ARGUMENTS "-E -x c++")
+ set(CODE_GENERATOR_PREPROCESSOR_WITH_LINEMARKERS "${CODE_GENERATOR_PREPROCESSOR_EXECUTABLE} ${CODE_GENERATOR_PREPROCESSOR_WITH_LINEMARKERS_ARGUMENTS}")
+endif ()
+
+option(USE_THIN_ARCHIVES "Produce all static libraries as thin archives" ON)
+if (USE_THIN_ARCHIVES)
+ execute_process(COMMAND ${CMAKE_AR} -V OUTPUT_VARIABLE AR_VERSION)
+ if ("${AR_VERSION}" MATCHES "^GNU ar")
+ set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> crT <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> crT <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> rT <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> rT <TARGET> <LINK_FLAGS> <OBJECTS>")
+ endif ()
+endif ()
+
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+define_property(TARGET PROPERTY FOLDER INHERITED BRIEF_DOCS "folder" FULL_DOCS "IDE folder name")
+
+if (COMPILER_IS_GCC_OR_CLANG)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-exceptions -fno-strict-aliasing")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-strict-aliasing -fno-rtti")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y")
+endif ()
+
+if (COMPILER_IS_CLANG AND CMAKE_GENERATOR STREQUAL "Ninja")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcolor-diagnostics")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
+endif ()
+
+if (WIN32 AND COMPILER_IS_GCC_OR_CLANG)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-ms-bitfields -Wno-unknown-pragmas")
+ add_definitions(-D__USE_MINGW_ANSI_STDIO=1)
+endif ()
+
+# Ensure that the default include system directories are added to the list of CMake implicit includes.
+# This workarounds an issue that happens when using GCC 6 and using system includes (-isystem).
+# For more details check: https://bugs.webkit.org/show_bug.cgi?id=161697
+macro(DETERMINE_GCC_SYSTEM_INCLUDE_DIRS _lang _compiler _flags _result)
+ file(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/dummy" "\n")
+ separate_arguments(_buildFlags UNIX_COMMAND "${_flags}")
+ execute_process(COMMAND ${_compiler} ${_buildFlags} -v -E -x ${_lang} -dD dummy
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/CMakeFiles OUTPUT_QUIET
+ ERROR_VARIABLE _gccOutput)
+ file(REMOVE "${CMAKE_BINARY_DIR}/CMakeFiles/dummy")
+ if ("${_gccOutput}" MATCHES "> search starts here[^\n]+\n *(.+) *\n *End of (search) list")
+ set(${_result} ${CMAKE_MATCH_1})
+ string(REPLACE "\n" " " ${_result} "${${_result}}")
+ separate_arguments(${_result})
+ endif ()
+endmacro()
+
+if (CMAKE_COMPILER_IS_GNUCC)
+ DETERMINE_GCC_SYSTEM_INCLUDE_DIRS("c" "${CMAKE_C_COMPILER}" "${CMAKE_C_FLAGS}" SYSTEM_INCLUDE_DIRS)
+ set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES} ${SYSTEM_INCLUDE_DIRS})
+endif ()
+
+if (CMAKE_COMPILER_IS_GNUCXX)
+ DETERMINE_GCC_SYSTEM_INCLUDE_DIRS("c++" "${CMAKE_CXX_COMPILER}" "${CMAKE_CXX_FLAGS}" SYSTEM_INCLUDE_DIRS)
+ set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES} ${SYSTEM_INCLUDE_DIRS})
+endif ()
+
+# Detect Cortex-A53 core if CPU is ARM64 and OS is Linux.
+# Query /proc/cpuinfo for each available core and check reported CPU part number: 0xd03 signals Cortex-A53.
+# (see Main ID Register in ARM Cortex-A53 MPCore Processor Technical Reference Manual)
+set(WTF_CPU_ARM64_CORTEXA53_INITIALVALUE OFF)
+if (WTF_CPU_ARM64 AND (${CMAKE_SYSTEM_NAME} STREQUAL "Linux"))
+ execute_process(COMMAND nproc OUTPUT_VARIABLE PROC_COUNT)
+ math(EXPR PROC_MAX ${PROC_COUNT}-1)
+ foreach (PROC_ID RANGE ${PROC_MAX})
+ execute_process(COMMAND taskset -c ${PROC_ID} grep "^CPU part" /proc/cpuinfo OUTPUT_VARIABLE PROC_PART)
+ if (PROC_PART MATCHES "0xd03")
+ set(WTF_CPU_ARM64_CORTEXA53_INITIALVALUE ON)
+ break ()
+ endif ()
+ endforeach ()
+endif ()
+option(WTF_CPU_ARM64_CORTEXA53 "Enable Cortex-A53-specific code paths" ${WTF_CPU_ARM64_CORTEXA53_INITIALVALUE})
+
+if (WTF_CPU_ARM64_CORTEXA53)
+ if (NOT WTF_CPU_ARM64)
+ message(FATAL_ERROR "WTF_CPU_ARM64_CORTEXA53 set without WTF_CPU_ARM64")
+ endif ()
+ include(TestCXXAcceptsFlag)
+ CHECK_CXX_ACCEPTS_FLAG(-mfix-cortex-a53-835769 CXX_ACCEPTS_MFIX_CORTEX_A53_835769)
+ if (CXX_ACCEPTS_MFIX_CORTEX_A53_835769)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfix-cortex-a53-835769")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfix-cortex-a53-835769")
+ message(STATUS "Enabling Cortex-A53 workaround for compiler and disabling GNU gold linker, because it doesn't support this workaround.")
+ endif ()
+endif ()
+
+EXPOSE_VARIABLE_TO_BUILD(WTF_CPU_ARM64_CORTEXA53)
+
+set(ARM_TRADITIONAL_DETECTED FALSE)
+if (WTF_CPU_ARM)
+ set(ARM_THUMB2_TEST_SOURCE
+ "
+ #if !defined(thumb2) && !defined(__thumb2__)
+ #error \"Thumb2 instruction set isn't available\"
+ #endif
+ int main() {}
+ ")
+
+ include(CheckCXXSourceCompiles)
+ CHECK_CXX_SOURCE_COMPILES("${ARM_THUMB2_TEST_SOURCE}" ARM_THUMB2_DETECTED)
+ if (NOT ARM_THUMB2_DETECTED)
+ set(ARM_TRADITIONAL_DETECTED TRUE)
+ # See https://bugs.webkit.org/show_bug.cgi?id=159880#c4 for details.
+ message(STATUS "Disabling GNU gold linker, because it doesn't support ARM instruction set properly.")
+ endif ()
+endif ()
+
+# Use ld.gold if it is available and isn't disabled explicitly
+include(CMakeDependentOption)
+CMAKE_DEPENDENT_OPTION(USE_LD_GOLD "Use GNU gold linker" ON
+ "NOT CXX_ACCEPTS_MFIX_CORTEX_A53_835769;NOT ARM_TRADITIONAL_DETECTED;NOT WIN32;NOT APPLE" OFF)
+if (USE_LD_GOLD)
+ execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
+ if ("${LD_VERSION}" MATCHES "GNU gold")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
+ else ()
+ message(WARNING "GNU gold linker isn't available, using the default system linker.")
+ set(USE_LD_GOLD OFF)
+ endif ()
+endif ()
+
+set(ENABLE_DEBUG_FISSION_DEFAULT OFF)
+if (USE_LD_GOLD AND CMAKE_BUILD_TYPE STREQUAL "Debug")
+ include(TestCXXAcceptsFlag)
+ CHECK_CXX_ACCEPTS_FLAG(-gsplit-dwarf CXX_ACCEPTS_GSPLIT_DWARF)
+ if (CXX_ACCEPTS_GSPLIT_DWARF)
+ set(ENABLE_DEBUG_FISSION_DEFAULT ON)
+ endif ()
+endif ()
+
+option(DEBUG_FISSION "Use Debug Fission support" ${ENABLE_DEBUG_FISSION_DEFAULT})
+
+if (DEBUG_FISSION)
+ if (NOT USE_LD_GOLD)
+ message(FATAL_ERROR "Need GNU gold linker for Debug Fission support")
+ endif ()
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -gsplit-dwarf")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -gsplit-dwarf")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gdb-index")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gdb-index")
+endif ()
+
+if (COMPILER_IS_CLANG)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Qunused-arguments")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments")
+endif ()
+
+string(TOLOWER ${CMAKE_HOST_SYSTEM_PROCESSOR} LOWERCASE_CMAKE_HOST_SYSTEM_PROCESSOR)
+if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND "${LOWERCASE_CMAKE_HOST_SYSTEM_PROCESSOR}" MATCHES "(i[3-6]86|x86|armhf)")
+ # To avoid out of memory when building with debug option in 32bit system.
+ # See https://bugs.webkit.org/show_bug.cgi?id=77327
+ set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "-Wl,--no-keep-memory ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
+endif ()
+
+if (NOT MSVC)
+ string(REGEX MATCHALL "-fsanitize=[^ ]*" ENABLED_COMPILER_SANITIZERS ${CMAKE_CXX_FLAGS})
+endif ()
+
+if (UNIX AND NOT APPLE AND NOT ENABLED_COMPILER_SANITIZERS)
+ set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined ${CMAKE_SHARED_LINKER_FLAGS}")
+endif ()
+
+if (USE_ARM_LLVM_DISASSEMBLER)
+ find_package(LLVM REQUIRED)
+ SET_AND_EXPOSE_TO_BUILD(HAVE_LLVM TRUE)
+endif ()
+
+# Enable the usage of OpenMP.
+# - At this moment, OpenMP is only used as an alternative implementation
+# to native threads for the parallelization of the SVG filters.
+if (USE_OPENMP)
+ find_package(OpenMP REQUIRED)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
+endif ()
+
+# GTK uses the GNU installation directories as defaults.
+if (NOT PORT STREQUAL "GTK")
+ set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Absolute path to library installation directory")
+ set(EXEC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Absolute path to executable installation directory")
+ set(LIBEXEC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Absolute path to install executables executed by the library")
+endif ()
+
+# The Ninja generator does not yet know how to build archives in pieces, and so response
+# files must be used to deal with very long linker command lines.
+# See https://bugs.webkit.org/show_bug.cgi?id=129771
+# The Apple Toolchain doesn't support response files.
+if (NOT APPLE)
+ # If using Ninja with cmake >= 3.6.0 and icecream, then the build is broken
+ # if enable the response files. See https://bugs.webkit.org/show_bug.cgi?id=168770
+ if (NOT ((${CMAKE_CXX_COMPILER} MATCHES ".*icecc.*") AND (CMAKE_GENERATOR STREQUAL "Ninja") AND (${CMAKE_VERSION} VERSION_GREATER 3.5)))
+ set(CMAKE_NINJA_FORCE_RESPONSE_FILE 1)
+ endif ()
+endif ()
+
+# Macros for determining HAVE values.
+include(CheckIncludeFile)
+include(CheckFunctionExists)
+include(CheckSymbolExists)
+include(CheckStructHasMember)
+
+macro(_HAVE_CHECK_INCLUDE _variable _header)
+ check_include_file(${_header} ${_variable}_value)
+ SET_AND_EXPOSE_TO_BUILD(${_variable} ${_variable}_value)
+endmacro()
+
+macro(_HAVE_CHECK_FUNCTION _variable _function)
+ check_function_exists(${_function} ${_variable}_value)
+ SET_AND_EXPOSE_TO_BUILD(${_variable} ${_variable}_value)
+endmacro()
+
+macro(_HAVE_CHECK_SYMBOL _variable _symbol _header)
+ check_symbol_exists(${_symbol} ${_header} ${_variable}_value)
+ SET_AND_EXPOSE_TO_BUILD(${_variable} ${_variable}_value)
+endmacro()
+
+macro(_HAVE_CHECK_STRUCT _variable _struct _member _header)
+ check_struct_has_member(${_struct} ${_member} ${_header} ${_variable}_value)
+ SET_AND_EXPOSE_TO_BUILD(${_variable} ${_variable}_value)
+endmacro()
+
+# Check whether features.h header exists.
+# Including glibc's one defines __GLIBC__, that is used in Platform.h
+_HAVE_CHECK_INCLUDE(HAVE_FEATURES_H features.h)
+
+# Check for headers
+_HAVE_CHECK_INCLUDE(HAVE_ERRNO_H errno.h)
+_HAVE_CHECK_INCLUDE(HAVE_LANGINFO_H langinfo.h)
+_HAVE_CHECK_INCLUDE(HAVE_MMAP sys/mman.h)
+_HAVE_CHECK_INCLUDE(HAVE_PTHREAD_NP_H pthread_np.h)
+_HAVE_CHECK_INCLUDE(HAVE_STRINGS_H strings.h)
+_HAVE_CHECK_INCLUDE(HAVE_SYS_PARAM_H sys/param.h)
+_HAVE_CHECK_INCLUDE(HAVE_SYS_TIME_H sys/time.h)
+_HAVE_CHECK_INCLUDE(HAVE_SYS_TIMEB_H sys/timeb.h)
+
+# Check for functions
+_HAVE_CHECK_FUNCTION(HAVE_ALIGNED_MALLOC _aligned_malloc)
+_HAVE_CHECK_FUNCTION(HAVE_ISDEBUGGERPRESENT IsDebuggerPresent)
+_HAVE_CHECK_FUNCTION(HAVE_LOCALTIME_R localtime_r)
+_HAVE_CHECK_FUNCTION(HAVE_STRNSTR strnstr)
+_HAVE_CHECK_FUNCTION(HAVE_TIMEGM timegm)
+_HAVE_CHECK_FUNCTION(HAVE_VASPRINTF vasprintf)
+
+# Check for symbols
+# Windows has signal.h but is missing symbols that are used in calls to signal.
+_HAVE_CHECK_SYMBOL(HAVE_SIGNAL_H SIGTRAP signal.h)
+
+# Check for struct members
+_HAVE_CHECK_STRUCT(HAVE_STAT_BIRTHTIME "struct stat" st_birthtime sys/stat.h)
+_HAVE_CHECK_STRUCT(HAVE_TM_GMTOFF "struct tm" tm_gmtoff time.h)
+_HAVE_CHECK_STRUCT(HAVE_TM_ZONE "struct tm" tm_zone time.h)
diff --git a/weex_core/Source/android/jsengine/dependence/OptionsJSCOnly.cmake b/weex_core/Source/android/jsengine/dependence/OptionsJSCOnly.cmake
new file mode 100644
index 0000000000..d91e657c9b
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/OptionsJSCOnly.cmake
@@ -0,0 +1,75 @@
+# find_package(Threads REQUIRED)
+
+add_definitions(-DBUILDING_JSCONLY__)
+
+set(PROJECT_VERSION_MAJOR 1)
+set(PROJECT_VERSION_MINOR 0)
+set(PROJECT_VERSION_MICRO 0)
+set(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_MICRO})
+
+set(ALL_EVENT_LOOP_TYPES
+ GLib
+ Generic
+)
+
+set(DEFAULT_EVENT_LOOP_TYPE "Generic")
+
+set(EVENT_LOOP_TYPE ${DEFAULT_EVENT_LOOP_TYPE} CACHE STRING "Implementation of event loop to be used in JavaScriptCore (one of ${ALL_EVENT_LOOP_TYPES})")
+
+if (WTF_CPU_X86 OR WTF_CPU_X86_64)
+ SET_AND_EXPOSE_TO_BUILD(USE_UDIS86 1)
+endif ()
+
+if (ENABLE_STATIC_JSC)
+ set(JavaScriptCore_LIBRARY_TYPE STATIC)
+endif ()
+
+string(TOLOWER ${EVENT_LOOP_TYPE} LOWERCASE_EVENT_LOOP_TYPE)
+if (LOWERCASE_EVENT_LOOP_TYPE STREQUAL "glib")
+ find_package(GLIB 2.36 REQUIRED COMPONENTS gio gobject)
+ SET_AND_EXPOSE_TO_BUILD(USE_GLIB 1)
+ SET_AND_EXPOSE_TO_BUILD(USE_GLIB_EVENT_LOOP 1)
+ SET_AND_EXPOSE_TO_BUILD(WTF_DEFAULT_EVENT_LOOP 0)
+else ()
+ SET_AND_EXPOSE_TO_BUILD(USE_GENERIC_EVENT_LOOP 1)
+ SET_AND_EXPOSE_TO_BUILD(WTF_DEFAULT_EVENT_LOOP 0)
+endif ()
+
+#if (NOT APPLE)
+# # find_package(ICU REQUIRED)
+#else ()
+# set(ICU_INCLUDE_DIRS
+# "${WEBCORE_DIR}/icu"
+# "${JAVASCRIPTCORE_DIR}/icu"
+# "${WTF_DIR}/icu"
+# )
+# set(ICU_LIBRARIES libicucore.dylib)
+#endif ()
+
+set(ICU_INCLUDE_DIRS
+ "${COMMON_ICU_DIR}"
+ "${WTF_DIR}/icu"
+)
+message("bbbbbbbbbbbbbbbbb ${COMMON_ICU_DIR}")
+
+# From OptionsGTK.cmake
+if (CMAKE_MAJOR_VERSION LESS 3)
+ # Before CMake 3 it was necessary to use a build script instead of using cmake --build directly
+ # to preserve colors and pretty-printing.
+
+ build_command(COMMAND_LINE_TO_BUILD)
+ # build_command unconditionally adds -i (ignore errors) for make, and there's
+ # no reasonable way to turn that off, so we just replace it with -k, which has
+ # the same effect, except that the return code will indicate that an error occurred.
+ # See: http://www.cmake.org/cmake/help/v3.0/command/build_command.html
+ string(REPLACE " -i" " -k" COMMAND_LINE_TO_BUILD ${COMMAND_LINE_TO_BUILD})
+ file(WRITE
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/build.sh
+ "#!/bin/sh\n"
+ "${COMMAND_LINE_TO_BUILD} $@"
+ )
+ file(COPY ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/build.sh
+ DESTINATION ${CMAKE_BINARY_DIR}
+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE
+ )
+endif ()
diff --git a/weex_core/Source/android/jsengine/dependence/WeexCommon.cmake b/weex_core/Source/android/jsengine/dependence/WeexCommon.cmake
new file mode 100644
index 0000000000..bbae8959a6
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/WeexCommon.cmake
@@ -0,0 +1,42 @@
+# -----------------------------------------------------------------------------
+# This file is included individually from various subdirectories (JSC, WTF,
+# WebCore, Weex) in order to allow scripts to build only part of WebKit.
+# We want to run this file only once.
+# -----------------------------------------------------------------------------
+if (NOT HAS_RUN_WEEX_COMMON)
+ set(HAS_RUN_WEEX_COMMON TRUE)
+
+ # -----------------------------------------------------------------------------
+ # Find common packages (used by all ports)
+ # -----------------------------------------------------------------------------
+
+ # TODO Enforce version requirement for gperf
+
+ find_package(PythonInterp 2.7.0 REQUIRED)
+
+ # We cannot check for RUBY_FOUND because it is set only when the full package is installed and
+ # the only thing we need is the interpreter. Unlike Python, cmake does not provide a macro
+ # for finding only the Ruby interpreter.
+ find_package(Ruby 1.9)
+ if (NOT RUBY_EXECUTABLE OR RUBY_VERSION VERSION_LESS 1.9)
+ message(FATAL_ERROR "Ruby 1.9 or higher is required.")
+ endif ()
+
+ # -----------------------------------------------------------------------------
+ # Helper macros and feature defines
+ # -----------------------------------------------------------------------------
+
+ include(WeexMacros)
+ include(WeexFS)
+ include(WeexHelpers)
+ include(WeexFeatures)
+
+ include(OptionsCommon)
+ include(Options${PORT})
+
+ # -----------------------------------------------------------------------------
+ # config.h
+ # -----------------------------------------------------------------------------
+
+ CREATE_CONFIGURATION_HEADER()
+endif ()
diff --git a/weex_core/Source/android/jsengine/dependence/WeexFS.cmake b/weex_core/Source/android/jsengine/dependence/WeexFS.cmake
new file mode 100644
index 0000000000..6d1e656e50
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/WeexFS.cmake
@@ -0,0 +1,24 @@
+if (NOT BMALLOC_DIR)
+ set(BMALLOC_DIR "${CMAKE_MODULE_PATH}/Source/bmalloc")
+endif ()
+if (NOT WTF_DIR)
+ set(WTF_DIR "${CMAKE_MODULE_PATH}/WTF")
+ set(COMMON_ICU_DIR "${CMAKE_MODULE_PATH}/icu")
+endif ()
+if (NOT JAVASCRIPTCORE_DIR)
+ set(JAVASCRIPTCORE_DIR "${CMAKE_MODULE_PATH}/Source/JavaScriptCore")
+endif ()
+if (NOT TOOLS_DIR)
+ set(TOOLS_DIR "${CMAKE_SOURCE_DIR}/Tools")
+endif ()
+
+set(DERIVED_SOURCES_DIR "${CMAKE_BINARY_DIR}/DerivedSources")
+set(DERIVED_SOURCES_JAVASCRIPTCORE_DIR "${CMAKE_BINARY_DIR}/DerivedSources/JavaScriptCore")
+set(DERIVED_SOURCES_WEBINSPECTORUI_DIR "${CMAKE_BINARY_DIR}/DerivedSources/WebInspectorUI")
+
+file(MAKE_DIRECTORY ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR})
+file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/Source/JavaScriptCore/runtime)
+
+file(MAKE_DIRECTORY ${DERIVED_SOURCES_WEBINSPECTORUI_DIR})
+file(MAKE_DIRECTORY ${DERIVED_SOURCES_WEBINSPECTORUI_DIR}/Protocol)
+file(MAKE_DIRECTORY ${DERIVED_SOURCES_WEBINSPECTORUI_DIR}/UserInterface/Protocol)
diff --git a/weex_core/Source/android/jsengine/dependence/WeexFeatures.cmake b/weex_core/Source/android/jsengine/dependence/WeexFeatures.cmake
new file mode 100644
index 0000000000..bd59d95ae4
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/WeexFeatures.cmake
@@ -0,0 +1,357 @@
+# The settings in this file are the WebKit project default values, and
+# are recommended for most ports. Ports can override these settings in
+# Options*.cmake, but should do so only if there is strong reason to
+# deviate from the defaults of the WebKit project (e.g. if the feature
+# requires platform-specific implementation that does not exist).
+#
+# Most defaults in this file affect end users but not developers.
+# Defaults for development builds are set in FeatureList.pm. Most all
+# features enabled here should also be enabled in FeatureList.pm.
+
+set(_WEEX_AVAILABLE_OPTIONS "")
+
+set(PUBLIC YES)
+set(PRIVATE NO)
+
+macro(_ENSURE_OPTION_MODIFICATION_IS_ALLOWED)
+ if (NOT _SETTING_WEEX_OPTIONS)
+ message(FATAL_ERROR "Options must be set between WEEX_OPTION_BEGIN and WEEX_OPTION_END")
+ endif ()
+endmacro()
+
+macro(_ENSURE_IS_WEEX_OPTION _name)
+ list(FIND _WEEX_AVAILABLE_OPTIONS ${_name} ${_name}_OPTION_INDEX)
+ if (${_name}_OPTION_INDEX EQUAL -1)
+ message(FATAL_ERROR "${_name} is not a valid WebKit option")
+ endif ()
+endmacro()
+
+macro(WEEX_OPTION_DEFINE _name _description _public _initial_value)
+ _ENSURE_OPTION_MODIFICATION_IS_ALLOWED()
+
+ set(_WEEX_AVAILABLE_OPTIONS_DESCRIPTION_${_name} ${_description})
+ set(_WEEX_AVAILABLE_OPTIONS_IS_PUBLIC_${_name} ${_public})
+ set(_WEEX_AVAILABLE_OPTIONS_INITIAL_VALUE_${_name} ${_initial_value})
+ set(_WEEX_AVAILABLE_OPTIONS_${_name}_CONFLICTS "")
+ set(_WEEX_AVAILABLE_OPTIONS_${_name}_DEPENDENCIES "")
+ list(APPEND _WEEX_AVAILABLE_OPTIONS ${_name})
+
+ EXPOSE_VARIABLE_TO_BUILD(${_name})
+endmacro()
+
+macro(WEEX_OPTION_DEFAULT_PORT_VALUE _name _public _value)
+ _ENSURE_OPTION_MODIFICATION_IS_ALLOWED()
+ _ENSURE_IS_WEEX_OPTION(${_name})
+
+ set(_WEEX_AVAILABLE_OPTIONS_IS_PUBLIC_${_name} ${_public})
+ set(_WEEX_AVAILABLE_OPTIONS_INITIAL_VALUE_${_name} ${_value})
+endmacro()
+
+macro(WEEX_OPTION_CONFLICT _name _conflict)
+ _ENSURE_OPTION_MODIFICATION_IS_ALLOWED()
+ _ENSURE_IS_WEEX_OPTION(${_name})
+ _ENSURE_IS_WEEX_OPTION(${_conflict})
+
+ list(APPEND _WEEX_AVAILABLE_OPTIONS_${_name}_CONFLICTS ${_conflict})
+endmacro()
+
+macro(WEEX_OPTION_DEPEND _name _depend)
+ _ENSURE_OPTION_MODIFICATION_IS_ALLOWED()
+ _ENSURE_IS_WEEX_OPTION(${_name})
+ _ENSURE_IS_WEEX_OPTION(${_depend})
+
+ list(APPEND _WEEX_AVAILABLE_OPTIONS_${_name}_DEPENDENCIES ${_depend})
+endmacro()
+
+macro(WEEX_OPTION_BEGIN)
+ set(_SETTING_WEEX_OPTIONS TRUE)
+
+ if (WTF_CPU_X86_64)
+ set(ENABLE_FTL_DEFAULT ON)
+ else ()
+ set(ENABLE_FTL_DEFAULT ON)
+ endif ()
+
+ WEEX_OPTION_DEFINE(ENABLE_3D_TRANSFORMS "Toggle 3D transforms support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_ACCELERATED_2D_CANVAS "Toggle accelerated 2D canvas support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_ACCELERATED_OVERFLOW_SCROLLING "Toggle accelerated scrolling support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_ACCESSIBILITY "Toggle accessibility support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_ALLINONE_BUILD "Toggle all-in-one build" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_API_TESTS "Enable public API unit tests" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_ASYNC_SCROLLING "Enable asynchronouse scrolling" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_ATTACHMENT_ELEMENT "Toggle attachment element support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_AVF_CAPTIONS "Toggle AVFoundation caption support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_CACHE_PARTITIONING "Toggle cache partitioning support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_CANVAS_PATH "Toggle Canvas Path support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_CANVAS_PROXY "Toggle CanvasProxy support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_CHANNEL_MESSAGING "Toggle MessageChannel and MessagePort support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_CONTENT_FILTERING "Toggle content filtering support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_CONTEXT_MENUS "Toggle Context Menu support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_CSS3_TEXT "Toggle CSS3 Text support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_CSS_BOX_DECORATION_BREAK "Toggle Box Decoration break (CSS Backgrounds and Borders) support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_CSS_COMPOSITING "Toggle CSS COMPOSITING support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_CSS_DEVICE_ADAPTATION "Toggle CSS Device Adaptation support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_CSS_IMAGE_ORIENTATION "Toggle CSS image-orientation support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_CSS_IMAGE_RESOLUTION "Toggle CSS image-resolution support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_CSS_REGIONS "Toggle CSS regions support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_CSS_SCROLL_SNAP "Toggle CSS snap scroll support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_CSS_SELECTORS_LEVEL4 "Toggle CSS Selectors Level 4 support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_CURSOR_VISIBILITY "Toggle cursor visibility support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_CUSTOM_SCHEME_HANDLER "Toggle Custom Scheme Handler support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_DASHBOARD_SUPPORT "Toggle dashboard support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_DATABASE_PROCESS "Toggle database process support in WebKit2" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_DATACUE_VALUE "Toggle datacue value support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_DATALIST_ELEMENT "Toggle HTML5 datalist support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_DATA_TRANSFER_ITEMS "Toggle HTML5 data transfer items support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_DEVICE_ORIENTATION "Toggle DeviceOrientation support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_DFG_JIT "Toggle data flow graph JIT tier" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_DOWNLOAD_ATTRIBUTE "Toggle download attribute support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_DRAG_SUPPORT "Toggle Drag Support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_ENCRYPTED_MEDIA "Toggle EME support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_FETCH_API "Toggle Fetch API support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_FILTERS_LEVEL_2 "Toggle Filters Module Level 2" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_FONT_LOAD_EVENTS "Toggle Font Load Events support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_FTPDIR "Toggle FTP directory support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_FTL_JIT "Toggle FTL support for JSC" PRIVATE ${ENABLE_FTL_DEFAULT})
+ WEEX_OPTION_DEFINE(ENABLE_FULLSCREEN_API "Toggle Fullscreen API support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_GAMEPAD "Toggle Gamepad support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_GAMEPAD_DEPRECATED "Toggle deprecated Gamepad support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_GEOLOCATION "Toggle Geolocation support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_ICONDATABASE "Toggle Icon database support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_IMAGE_DECODER_DOWN_SAMPLING "Toggle image decoder down sampling support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_INDEXED_DATABASE "Toggle Indexed Database API support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_INDEXED_DATABASE_IN_WORKERS "Toggle support for indexed database in workers" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_INDIE_UI "Toggle Indie UI support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_INPUT_TYPE_COLOR "Toggle Color Input support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_INPUT_TYPE_COLOR_POPOVER "Toggle popover color input support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_INPUT_TYPE_DATE "Toggle date type <input> support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE "Toggle broken datetime type <input> support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_INPUT_TYPE_DATETIMELOCAL "Toggle datetime-local type <input> support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_INPUT_TYPE_MONTH "Toggle month type <input> support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_INPUT_TYPE_TIME "Toggle time type <input> support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_INPUT_TYPE_WEEK "Toggle week type <input> support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_INTERSECTION_OBSERVER "Enable Intersection Observer support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_INTL "Toggle Intl support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_IOS_AIRPLAY "Toggle iOS airplay support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_JIT "Enable JustInTime javascript support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_LEGACY_CSS_VENDOR_PREFIXES "Toggle legacy css vendor prefix support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_LEGACY_ENCRYPTED_MEDIA "Support legacy EME" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_LEGACY_NOTIFICATIONS "Toggle Legacy Desktop Notifications Support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_LEGACY_VENDOR_PREFIXES "Toggle Legacy Vendor Prefix Support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_LETTERPRESS "Toggle letterpress support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_LINK_PREFETCH "Toggle pre fetching support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_MAC_LONG_PRESS "Toggle mac long press support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_MATHML "Toggle MathML support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_MEDIA_CAPTURE "Toggle Media Capture support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_MEDIA_CONTROLS_SCRIPT "Toggle definition of media controls in Javascript" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_MEDIA_SOURCE "Toggle Media Source support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_MEDIA_STREAM "Toggle Media Stream support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_MEDIA_STATISTICS "Toggle Media Statistics support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_MEMORY_SAMPLER "Toggle Memory Sampler support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_METER_ELEMENT "Toggle Meter Tag support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_MHTML "Toggle MHTML support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_MINIBROWSER "Whether to enable MiniBrowser compilation." PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_MOUSE_CURSOR_SCALE "Toggle Scaled mouse cursor support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_NAVIGATOR_CONTENT_UTILS "Toggle Navigator Content Utils support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_NAVIGATOR_HWCONCURRENCY "Toggle Navigator hardware concurrency support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_NOSNIFF "Toggle support for 'X-Content-Type-Options: nosniff'" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_NETSCAPE_PLUGIN_API "Toggle Netscape Plugin support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_NOTIFICATIONS "Toggle Desktop Notifications Support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_ORIENTATION_EVENTS "Toggle Orientation Events support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_PDFKIT_PLUGIN "Toggle PDFKit plugin support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_POINTER_LOCK "Toggle pointer lock support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_PROXIMITY_EVENTS "Toggle Proximity Events support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_PUBLIC_SUFFIX_LIST "Toggle public suffix list support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_QUOTA "Toggle Quota support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_READABLE_STREAM_API "Toggle ReadableStream API support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_READABLE_BYTE_STREAM_API "Toggle support of ReadableStream API byte stream part" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_REMOTE_INSPECTOR "Toggle remote inspector support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_RESOLUTION_MEDIA_QUERY "Toggle resolution media query support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_RESOURCE_USAGE "Toggle resource usage support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_RUBBER_BANDING "Toggle rubber banding support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_SAMPLING_PROFILER "Toggle sampling profiler support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_SERVICE_CONTROLS "Toggle service controls support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_SMOOTH_SCROLLING "Toggle smooth scrolling" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_SPEECH_SYNTHESIS "Toggle Speech Synthesis API support)" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_SPELLCHECK "Toggle Spellchecking support (requires Enchant)" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_SUBTLE_CRYPTO "Toggle subtle crypto support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_SVG_FONTS "Toggle SVG fonts support (imples SVG support)" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_TELEPHONE_NUMBER_DETECTION "Toggle telephone number detection support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_TEXT_AUTOSIZING "Toggle automatic text size adjustment support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_TOUCH_EVENTS "Toggle Touch Events support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_TOUCH_SLIDER "Toggle Touch Slider support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_TOUCH_ICON_LOADING "Toggle Touch Icon Loading Support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_USERSELECT_ALL "Toggle user-select:all support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_USER_MESSAGE_HANDLERS "Toggle user script message handler support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_VIBRATION "Toggle Vibration API support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_VIDEO "Toggle Video support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_VIDEO_TRACK "Toggle Track support for HTML5 video" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_VIEW_MODE_CSS_MEDIA "Toggle Track support for the view-mode media Feature" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_WEBASSEMBLY "Toggle WebAssembly support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_WEBGL "Toggle WebGL support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_WEBGL2 "Toggle WebGL 2.0 support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_WEBGPU "Toggle WebGPU support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_WEBVTT_REGIONS "Toggle webvtt region support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_WEB_ANIMATIONS "Toggle Web Animations support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_WEB_AUDIO "Toggle Web Audio support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_WEB_REPLAY "Toggle Web Replay support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_WEB_RTC "Toggle WebRTC API support" PRIVATE OFF)
+ WEEX_OPTION_DEFINE(ENABLE_WEB_SOCKETS "Toggle Web Sockets support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_WEB_TIMING "Toggle Web Timing support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_WRITABLE_STREAM_API "Toggle WritableStream API support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(ENABLE_XSLT "Toggle XSLT support" PRIVATE ON)
+ WEEX_OPTION_DEFINE(USE_SYSTEM_MALLOC "Toggle system allocator instead of WebKit's custom allocator" PRIVATE OFF)
+
+ WEEX_OPTION_DEPEND(ENABLE_WEB_RTC ENABLE_MEDIA_STREAM)
+ WEEX_OPTION_DEPEND(ENABLE_LEGACY_ENCRYPTED_MEDIA ENABLE_VIDEO)
+ WEEX_OPTION_DEPEND(ENABLE_DFG_JIT ENABLE_JIT)
+ WEEX_OPTION_DEPEND(ENABLE_FTL_JIT ENABLE_DFG_JIT)
+ WEEX_OPTION_DEPEND(ENABLE_WEBASSEMBLY ENABLE_FTL_JIT)
+ WEEX_OPTION_DEPEND(ENABLE_SAMPLING_PROFILER ENABLE_JIT)
+ WEEX_OPTION_DEPEND(ENABLE_INDEXED_DATABASE_IN_WORKERS ENABLE_INDEXED_DATABASE)
+ WEEX_OPTION_DEPEND(ENABLE_MEDIA_CONTROLS_SCRIPT ENABLE_VIDEO)
+ WEEX_OPTION_DEPEND(ENABLE_MEDIA_SOURCE ENABLE_VIDEO)
+ WEEX_OPTION_DEPEND(ENABLE_VIDEO_TRACK ENABLE_VIDEO)
+ WEEX_OPTION_DEPEND(ENABLE_TOUCH_SLIDER ENABLE_TOUCH_EVENTS)
+endmacro()
+
+macro(_WEEX_OPTION_ENFORCE_DEPENDS _name)
+ foreach (_dependency ${_WEEX_AVAILABLE_OPTIONS_${_name}_DEPENDENCIES})
+ if (NOT ${_dependency})
+ message(STATUS "Disabling ${_name} since ${_dependency} is disabled.")
+ set(${_name} OFF)
+ set(_OPTION_CHANGED TRUE)
+ break ()
+ endif ()
+ endforeach ()
+endmacro()
+
+macro(_WEEX_OPTION_ENFORCE_ALL_DEPENDS)
+ set(_OPTION_CHANGED TRUE)
+ while (${_OPTION_CHANGED})
+ set(_OPTION_CHANGED FALSE)
+ foreach (_name ${_WEEX_AVAILABLE_OPTIONS})
+ if (${_name})
+ _WEEX_OPTION_ENFORCE_DEPENDS(${_name})
+ endif ()
+ endforeach ()
+ endwhile ()
+endmacro()
+
+macro(_WEEX_OPTION_ENFORCE_CONFLICTS _name)
+ foreach (_conflict ${_WEEX_AVAILABLE_OPTIONS_${_name}_CONFLICTS})
+ if (${_conflict})
+ message(FATAL_ERROR "${_name} conflicts with ${_conflict}. You must disable one or the other.")
+ endif ()
+ endforeach ()
+endmacro()
+
+macro(_WEEX_OPTION_ENFORCE_ALL_CONFLICTS)
+ foreach (_name ${_WEEX_AVAILABLE_OPTIONS})
+ if (${_name})
+ _WEEX_OPTION_ENFORCE_CONFLICTS(${_name})
+ endif ()
+ endforeach ()
+endmacro()
+
+macro(WEEX_OPTION_END)
+ set(_SETTING_WEEX_OPTIONS FALSE)
+
+ list(SORT _WEEX_AVAILABLE_OPTIONS)
+ set(_MAX_FEATURE_LENGTH 0)
+ foreach (_name ${_WEEX_AVAILABLE_OPTIONS})
+ string(LENGTH ${_name} _name_length)
+ if (_name_length GREATER _MAX_FEATURE_LENGTH)
+ set(_MAX_FEATURE_LENGTH ${_name_length})
+ endif ()
+
+ option(${_name} "${_WEEX_AVAILABLE_OPTIONS_DESCRIPTION_${_name}}" ${_WEEX_AVAILABLE_OPTIONS_INITIAL_VALUE_${_name}})
+ if (NOT ${_WEEX_AVAILABLE_OPTIONS_IS_PUBLIC_${_name}})
+ mark_as_advanced(FORCE ${_name})
+ endif ()
+ endforeach ()
+
+ # Run through every possible depends to make sure we have disabled anything
+ # that could cause an unnecessary conflict before processing conflicts.
+ _WEEX_OPTION_ENFORCE_ALL_DEPENDS()
+ _WEEX_OPTION_ENFORCE_ALL_CONFLICTS()
+
+ foreach (_name ${_WEEX_AVAILABLE_OPTIONS})
+ if (${_name})
+ list(APPEND FEATURE_DEFINES ${_name})
+ set(FEATURE_DEFINES_WITH_SPACE_SEPARATOR "${FEATURE_DEFINES_WITH_SPACE_SEPARATOR} ${_name}")
+ endif ()
+ endforeach ()
+endmacro()
+
+macro(PRINT_WEEX_OPTIONS)
+ message(STATUS "Enabled features:")
+
+ set(_should_print_dots ON)
+ foreach (_name ${_WEEX_AVAILABLE_OPTIONS})
+ if (${_WEEX_AVAILABLE_OPTIONS_IS_PUBLIC_${_name}})
+ string(LENGTH ${_name} _name_length)
+ set(_message " ${_name} ")
+
+ # Print dots on every other row, for readability.
+ foreach (IGNORE RANGE ${_name_length} ${_MAX_FEATURE_LENGTH})
+ if (${_should_print_dots})
+ set(_message "${_message}.")
+ else ()
+ set(_message "${_message} ")
+ endif ()
+ endforeach ()
+
+ set(_should_print_dots (NOT ${_should_print_dots}))
+
+ set(_message "${_message} ${${_name}}")
+ message(STATUS "${_message}")
+ endif ()
+ endforeach ()
+endmacro()
+
+set(_WEEX_CONFIG_FILE_VARIABLES "")
+
+macro(EXPOSE_VARIABLE_TO_BUILD _variable_name)
+ list(APPEND _WEEX_CONFIG_FILE_VARIABLES ${_variable_name})
+endmacro()
+
+macro(SET_AND_EXPOSE_TO_BUILD _variable_name)
+ # It's important to handle the case where the value isn't passed, because often
+ # during configuration an empty variable is the result of a failed package search.
+ if (${ARGC} GREATER 1)
+ set(_variable_value ${ARGV1})
+ else ()
+ set(_variable_value OFF)
+ endif ()
+
+ set(${_variable_name} ${_variable_value})
+ EXPOSE_VARIABLE_TO_BUILD(${_variable_name})
+endmacro()
+
+macro(_ADD_CONFIGURATION_LINE_TO_HEADER_STRING _string _variable_name _output_variable_name)
+ if (${${_variable_name}})
+ set(${_string} "${_file_contents}#define ${_output_variable_name} 1\n")
+ else ()
+ set(${_string} "${_file_contents}#define ${_output_variable_name} 0\n")
+ endif ()
+endmacro()
+
+macro(CREATE_CONFIGURATION_HEADER)
+ list(SORT _WEEX_CONFIG_FILE_VARIABLES)
+ set(_file_contents "#ifndef CMAKECONFIG_H\n")
+ set(_file_contents "${_file_contents}#define CMAKECONFIG_H\n\n")
+
+ foreach (_variable_name ${_WEEX_CONFIG_FILE_VARIABLES})
+ _ADD_CONFIGURATION_LINE_TO_HEADER_STRING(_file_contents ${_variable_name} ${_variable_name})
+ endforeach ()
+ set(_file_contents "${_file_contents}\n#endif /* CMAKECONFIG_H */\n")
+
+ file(WRITE "${CMAKE_BINARY_DIR}/cmakeconfig.h.tmp" "${_file_contents}")
+ execute_process(COMMAND ${CMAKE_COMMAND}
+ -E copy_if_different
+ "${CMAKE_BINARY_DIR}/cmakeconfig.h.tmp"
+ "${CMAKE_BINARY_DIR}/cmakeconfig.h"
+ )
+ file(REMOVE "${CMAKE_BINARY_DIR}/cmakeconfig.h.tmp")
+endmacro()
diff --git a/weex_core/Source/android/jsengine/dependence/WeexHelpers.cmake b/weex_core/Source/android/jsengine/dependence/WeexHelpers.cmake
new file mode 100644
index 0000000000..4f637c2b69
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/WeexHelpers.cmake
@@ -0,0 +1,114 @@
+include(CMakeParseArguments)
+# Sets extra compile flags for a target, depending on the compiler being used.
+# Currently, only GCC is supported.
+macro(WEEX_SET_EXTRA_COMPILER_FLAGS _target)
+ set(options ENABLE_WERROR IGNORECXX_WARNINGS)
+ CMAKE_PARSE_ARGUMENTS("OPTION" "${options}" "" "" ${ARGN})
+ if (COMPILER_IS_GCC_OR_CLANG)
+ get_target_property(OLD_COMPILE_FLAGS ${_target} COMPILE_FLAGS)
+ if (${OLD_COMPILE_FLAGS} STREQUAL "OLD_COMPILE_FLAGS-NOTFOUND")
+ set(OLD_COMPILE_FLAGS "")
+ endif ()
+
+ if (NOT WIN32)
+ get_target_property(TARGET_TYPE ${_target} TYPE)
+ if (${TARGET_TYPE} STREQUAL "STATIC_LIBRARY") # -fPIC is automatically added to shared libraries
+ set(OLD_COMPILE_FLAGS "-fPIC ${OLD_COMPILE_FLAGS}")
+ endif ()
+ endif ()
+
+ # Suppress -Wparentheses-equality warning of Clang
+ if (COMPILER_IS_CLANG)
+ set(OLD_COMPILE_FLAGS "-Wno-parentheses-equality ${OLD_COMPILE_FLAGS}")
+ endif ()
+
+ # Suppress -Wmissing-field-initializers due to a GCC bug, see https://bugs.webkit.org/show_bug.cgi?id=157888 for details.
+ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION MATCHES "4\\.9")
+ set(OLD_COMPILE_FLAGS "-Wno-missing-field-initializers ${OLD_COMPILE_FLAGS}")
+ endif ()
+
+ # Enable warnings by default
+ if (NOT ${OPTION_IGNORECXX_WARNINGS})
+ set(OLD_COMPILE_FLAGS "-Wall -Wextra -Wcast-align -Wformat-security -Wmissing-format-attribute -Wpointer-arith -Wundef -Wwrite-strings ${OLD_COMPILE_FLAGS}")
+ endif ()
+
+ # Enable errors on warning
+ if (OPTION_ENABLE_WERROR)
+ set(OLD_COMPILE_FLAGS "-Werror ${OLD_COMPILE_FLAGS}")
+ endif ()
+
+ set_target_properties(${_target} PROPERTIES
+ COMPILE_FLAGS "${OLD_COMPILE_FLAGS}")
+
+ unset(OLD_COMPILE_FLAGS)
+ endif ()
+endmacro()
+
+
+# Append the given flag to the target property.
+# Builds on top of get_target_property() and set_target_properties()
+macro(ADD_TARGET_PROPERTIES _target _property _flags)
+ get_target_property(_tmp ${_target} ${_property})
+ if (NOT _tmp)
+ set(_tmp "")
+ endif (NOT _tmp)
+
+ foreach (f ${_flags})
+ set(_tmp "${_tmp} ${f}")
+ endforeach (f ${_flags})
+
+ set_target_properties(${_target} PROPERTIES ${_property} ${_tmp})
+ unset(_tmp)
+endmacro(ADD_TARGET_PROPERTIES _target _property _flags)
+
+
+# Append the given dependencies to the source file
+macro(ADD_SOURCE_DEPENDENCIES _source _deps)
+ get_source_file_property(_tmp ${_source} OBJECT_DEPENDS)
+ if (NOT _tmp)
+ set(_tmp "")
+ endif ()
+
+ foreach (f ${_deps})
+ list(APPEND _tmp "${f}")
+ endforeach ()
+
+ set_source_files_properties(${_source} PROPERTIES OBJECT_DEPENDS "${_tmp}")
+ unset(_tmp)
+endmacro()
+
+
+# Append the given dependencies to the source file
+# This one consider the given dependencies are in ${DERIVED_SOURCES_WEBCORE_DIR}
+# and prepends this to every member of dependencies list
+macro(ADD_SOURCE_WEBCORE_DERIVED_DEPENDENCIES _source _deps)
+ set(_tmp "")
+ foreach (f ${_deps})
+ list(APPEND _tmp "${DERIVED_SOURCES_WEBCORE_DIR}/${f}")
+ endforeach ()
+
+ ADD_SOURCE_DEPENDENCIES(${_source} ${_tmp})
+ unset(_tmp)
+endmacro()
+
+macro(CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE library_name current revision age)
+ math(EXPR ${library_name}_VERSION_MAJOR "${current} - ${age}")
+ set(${library_name}_VERSION_MINOR ${age})
+ set(${library_name}_VERSION_MICRO ${revision})
+ set(${library_name}_VERSION ${${library_name}_VERSION_MAJOR}.${age}.${revision})
+endmacro()
+
+macro(POPULATE_LIBRARY_VERSION library_name)
+if (NOT DEFINED ${library_name}_VERSION_MAJOR)
+ set(${library_name}_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
+endif ()
+if (NOT DEFINED ${library_name}_VERSION_MINOR)
+ set(${library_name}_VERSION_MINOR ${PROJECT_VERSION_MINOR})
+endif ()
+if (NOT DEFINED ${library_name}_VERSION_MICRO)
+ set(${library_name}_VERSION_MICRO ${PROJECT_VERSION_MICRO})
+endif ()
+if (NOT DEFINED ${library_name}_VERSION)
+ set(${library_name}_VERSION ${PROJECT_VERSION})
+endif ()
+endmacro()
diff --git a/weex_core/Source/android/jsengine/dependence/WeexMacros.cmake b/weex_core/Source/android/jsengine/dependence/WeexMacros.cmake
new file mode 100644
index 0000000000..19a5936d3d
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/WeexMacros.cmake
@@ -0,0 +1,447 @@
+include(CMakeParseArguments)
+include(ProcessorCount)
+ProcessorCount(PROCESSOR_COUNT)
+
+macro(WEEX_INCLUDE_CONFIG_FILES_IF_EXISTS)
+ set(_file ${CMAKE_CURRENT_SOURCE_DIR}/Platform${PORT}.cmake)
+ if (EXISTS ${_file})
+ message(STATUS "Using platform-specific CMakeLists: ${_file}")
+ include(${_file})
+ else ()
+ message(STATUS "Platform-specific CMakeLists not found: ${_file}")
+ endif ()
+endmacro()
+
+# Append the given dependencies to the source file
+macro(ADD_SOURCE_DEPENDENCIES _source _deps)
+ set(_tmp)
+ get_source_file_property(_tmp ${_source} OBJECT_DEPENDS)
+ if (NOT _tmp)
+ set(_tmp "")
+ endif ()
+
+ foreach (f ${_deps})
+ list(APPEND _tmp "${f}")
+ endforeach ()
+
+ set_source_files_properties(${_source} PROPERTIES OBJECT_DEPENDS "${_tmp}")
+endmacro()
+
+macro(ADD_PRECOMPILED_HEADER _header _cpp _source)
+ if (MSVC)
+ get_filename_component(PrecompiledBasename ${_cpp} NAME_WE)
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_source}")
+ set(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${_source}/${PrecompiledBasename}.pch")
+ set(_sources ${${_source}})
+
+ set_source_files_properties(${_cpp}
+ PROPERTIES COMPILE_FLAGS "/Yc\"${_header}\" /Fp\"${PrecompiledBinary}\""
+ OBJECT_OUTPUTS "${PrecompiledBinary}")
+ set_source_files_properties(${_sources}
+ PROPERTIES COMPILE_FLAGS "/Yu\"${_header}\" /FI\"${_header}\" /Fp\"${PrecompiledBinary}\""
+ OBJECT_DEPENDS "${PrecompiledBinary}")
+ list(APPEND ${_source} ${_cpp})
+ endif ()
+ #FIXME: Add support for Xcode.
+endmacro()
+
+option(SHOW_BINDINGS_GENERATION_PROGRESS "Show progress of generating bindings" OFF)
+
+# Helper macro which wraps generate-bindings-all.pl script.
+# target is a new target name to be added
+# OUTPUT_SOURCE is a list name which will contain generated sources.(eg. WebCore_SOURCES)
+# INPUT_FILES are IDL files to generate.
+# BASE_DIR is base directory where script is called.
+# IDL_INCLUDES is value of --include argument. (eg. ${WEBCORE_DIR}/bindings/js)
+# FEATURES is a value of --defines argument.
+# DESTINATION is a value of --outputDir argument.
+# GENERATOR is a value of --generator argument.
+# SUPPLEMENTAL_DEPFILE is a value of --supplementalDependencyFile. (optional)
+# PP_EXTRA_OUTPUT is extra outputs of preprocess-idls.pl. (optional)
+# PP_EXTRA_ARGS is extra arguments for preprocess-idls.pl. (optional)
+function(GENERATE_BINDINGS target)
+ set(options)
+ set(oneValueArgs OUTPUT_SOURCE BASE_DIR FEATURES DESTINATION GENERATOR SUPPLEMENTAL_DEPFILE)
+ set(multiValueArgs INPUT_FILES IDL_INCLUDES PP_EXTRA_OUTPUT PP_EXTRA_ARGS)
+ cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+ set(binding_generator ${WEBCORE_DIR}/bindings/scripts/generate-bindings-all.pl)
+ set(idl_attributes_file ${WEBCORE_DIR}/bindings/scripts/IDLAttributes.txt)
+ set(idl_files_list ${CMAKE_CURRENT_BINARY_DIR}/idl_files_${target}.tmp)
+ set(_supplemental_dependency)
+
+ set(content)
+ foreach (f ${arg_INPUT_FILES})
+ if (NOT IS_ABSOLUTE ${f})
+ set(f ${CMAKE_CURRENT_SOURCE_DIR}/${f})
+ endif ()
+ set(content "${content}${f}\n")
+ endforeach ()
+ file(WRITE ${idl_files_list} ${content})
+
+ set(args
+ --defines ${arg_FEATURES}
+ --generator ${arg_GENERATOR}
+ --outputDir ${arg_DESTINATION}
+ --idlFilesList ${idl_files_list}
+ --preprocessor "${CODE_GENERATOR_PREPROCESSOR}"
+ --idlAttributesFile ${idl_attributes_file})
+ if (arg_SUPPLEMENTAL_DEPFILE)
+ list(APPEND args --supplementalDependencyFile ${arg_SUPPLEMENTAL_DEPFILE})
+ endif ()
+ if (PROCESSOR_COUNT)
+ list(APPEND args --numOfJobs ${PROCESSOR_COUNT})
+ endif ()
+ foreach (i IN LISTS arg_IDL_INCLUDES)
+ if (IS_ABSOLUTE ${i})
+ list(APPEND args --include ${i})
+ else ()
+ list(APPEND args --include ${CMAKE_CURRENT_SOURCE_DIR}/${i})
+ endif ()
+ endforeach ()
+ foreach (i IN LISTS arg_PP_EXTRA_OUTPUT)
+ list(APPEND args --ppExtraOutput ${i})
+ endforeach ()
+ foreach (i IN LISTS arg_PP_EXTRA_ARGS)
+ list(APPEND args --ppExtraArgs ${i})
+ endforeach ()
+
+ set(common_generator_dependencies
+ ${WEBCORE_DIR}/bindings/scripts/generate-bindings.pl
+ ${SCRIPTS_BINDINGS}
+ # Changing enabled features should trigger recompiling all IDL files
+ # because some of them use #if.
+ ${CMAKE_BINARY_DIR}/cmakeconfig.h
+ )
+ if (EXISTS ${WEBCORE_DIR}/bindings/scripts/CodeGenerator${arg_GENERATOR}.pm)
+ list(APPEND common_generator_dependencies ${WEBCORE_DIR}/bindings/scripts/CodeGenerator${arg_GENERATOR}.pm)
+ endif ()
+ if (EXISTS ${arg_BASE_DIR}/CodeGenerator${arg_GENERATOR}.pm)
+ list(APPEND common_generator_dependencies ${arg_BASE_DIR}/CodeGenerator${arg_GENERATOR}.pm)
+ endif ()
+ foreach (i IN LISTS common_generator_dependencies)
+ list(APPEND args --generatorDependency ${i})
+ endforeach ()
+
+ set(gen_sources)
+ set(gen_headers)
+ foreach (_file ${arg_INPUT_FILES})
+ get_filename_component(_name ${_file} NAME_WE)
+ list(APPEND gen_sources ${arg_DESTINATION}/JS${_name}.cpp)
+ list(APPEND gen_headers ${arg_DESTINATION}/JS${_name}.h)
+ endforeach ()
+ set(${arg_OUTPUT_SOURCE} ${${arg_OUTPUT_SOURCE}} ${gen_sources} PARENT_SCOPE)
+ set(act_args)
+ if (SHOW_BINDINGS_GENERATION_PROGRESS)
+ list(APPEND args --showProgress)
+ endif ()
+ if (${CMAKE_VERSION} VERSION_LESS 3.2)
+ set_source_files_properties(${gen_sources} ${gen_headers} PROPERTIES GENERATED 1)
+ else ()
+ list(APPEND act_args BYPRODUCTS ${gen_sources} ${gen_headers})
+ if (SHOW_BINDINGS_GENERATION_PROGRESS)
+ list(APPEND act_args USES_TERMINAL)
+ endif ()
+ endif ()
+ add_custom_target(${target}
+ COMMAND ${PERL_EXECUTABLE} ${binding_generator} ${args}
+ WORKING_DIRECTORY ${arg_BASE_DIR}
+ COMMENT "Generate bindings (${target})"
+ VERBATIM ${act_args})
+endfunction()
+
+macro(GENERATE_FONT_NAMES _infile)
+ set(NAMES_GENERATOR ${WEBCORE_DIR}/dom/make_names.pl)
+ set(_arguments --fonts ${_infile})
+ set(_outputfiles ${DERIVED_SOURCES_WEBCORE_DIR}/WebKitFontFamilyNames.cpp ${DERIVED_SOURCES_WEBCORE_DIR}/WebKitFontFamilyNames.h)
+
+ add_custom_command(
+ OUTPUT ${_outputfiles}
+ MAIN_DEPENDENCY ${_infile}
+ DEPENDS ${MAKE_NAMES_DEPENDENCIES} ${NAMES_GENERATOR} ${SCRIPTS_BINDINGS}
+ COMMAND ${PERL_EXECUTABLE} ${NAMES_GENERATOR} --outputDir ${DERIVED_SOURCES_WEBCORE_DIR} ${_arguments}
+ VERBATIM)
+endmacro()
+
+
+macro(GENERATE_EVENT_FACTORY _infile _outfile)
+ set(NAMES_GENERATOR ${WEBCORE_DIR}/dom/make_event_factory.pl)
+
+ add_custom_command(
+ OUTPUT ${DERIVED_SOURCES_WEBCORE_DIR}/${_outfile}
+ MAIN_DEPENDENCY ${_infile}
+ DEPENDS ${NAMES_GENERATOR} ${SCRIPTS_BINDINGS}
+ COMMAND ${PERL_EXECUTABLE} ${NAMES_GENERATOR} --input ${_infile} --outputDir ${DERIVED_SOURCES_WEBCORE_DIR}
+ VERBATIM)
+endmacro()
+
+
+macro(GENERATE_EXCEPTION_CODE_DESCRIPTION _infile _outfile)
+ set(NAMES_GENERATOR ${WEBCORE_DIR}/dom/make_dom_exceptions.pl)
+
+ add_custom_command(
+ OUTPUT ${DERIVED_SOURCES_WEBCORE_DIR}/${_outfile}
+ MAIN_DEPENDENCY ${_infile}
+ DEPENDS ${NAMES_GENERATOR} ${SCRIPTS_BINDINGS}
+ COMMAND ${PERL_EXECUTABLE} ${NAMES_GENERATOR} --input ${_infile} --outputDir ${DERIVED_SOURCES_WEBCORE_DIR}
+ VERBATIM)
+endmacro()
+
+
+macro(GENERATE_SETTINGS_MACROS _infile _outfile)
+ set(NAMES_GENERATOR ${WEBCORE_DIR}/page/make_settings.pl)
+
+ # Do not list the output in more than one independent target that may
+ # build in parallel or the two instances of the rule may conflict.
+ # <https://cmake.org/cmake/help/v3.0/command/add_custom_command.html>
+ set(_extra_output
+ ${DERIVED_SOURCES_WEBCORE_DIR}/InternalSettingsGenerated.h
+ ${DERIVED_SOURCES_WEBCORE_DIR}/InternalSettingsGenerated.cpp
+ ${DERIVED_SOURCES_WEBCORE_DIR}/InternalSettingsGenerated.idl
+ )
+ set(_args BYPRODUCTS ${_extra_output})
+ if (${CMAKE_VERSION} VERSION_LESS 3.2)
+ set_source_files_properties(${_extra_output} PROPERTIES GENERATED 1)
+ set(_args)
+ endif ()
+ add_custom_command(
+ OUTPUT ${DERIVED_SOURCES_WEBCORE_DIR}/${_outfile}
+ MAIN_DEPENDENCY ${_infile}
+ DEPENDS ${NAMES_GENERATOR} ${SCRIPTS_BINDINGS}
+ COMMAND ${PERL_EXECUTABLE} ${NAMES_GENERATOR} --input ${_infile} --outputDir ${DERIVED_SOURCES_WEBCORE_DIR}
+ VERBATIM ${_args})
+endmacro()
+
+
+macro(GENERATE_DOM_NAMES _namespace _attrs)
+ set(NAMES_GENERATOR ${WEBCORE_DIR}/dom/make_names.pl)
+ set(_arguments --attrs ${_attrs})
+ set(_outputfiles ${DERIVED_SOURCES_WEBCORE_DIR}/${_namespace}Names.cpp ${DERIVED_SOURCES_WEBCORE_DIR}/${_namespace}Names.h)
+ set(_extradef)
+ set(_tags)
+
+ foreach (f ${ARGN})
+ if (_tags)
+ set(_extradef "${_extradef} ${f}")
+ else ()
+ set(_tags ${f})
+ endif ()
+ endforeach ()
+
+ if (_tags)
+ set(_arguments "${_arguments}" --tags ${_tags} --factory --wrapperFactory)
+ set(_outputfiles "${_outputfiles}" ${DERIVED_SOURCES_WEBCORE_DIR}/${_namespace}ElementFactory.cpp ${DERIVED_SOURCES_WEBCORE_DIR}/${_namespace}ElementFactory.h ${DERIVED_SOURCES_WEBCORE_DIR}/JS${_namespace}ElementWrapperFactory.cpp ${DERIVED_SOURCES_WEBCORE_DIR}/JS${_namespace}ElementWrapperFactory.h)
+ endif ()
+
+ if (_extradef)
+ set(_additionArguments "${_additionArguments}" --extraDefines=${_extradef})
+ endif ()
+
+ add_custom_command(
+ OUTPUT ${_outputfiles}
+ DEPENDS ${MAKE_NAMES_DEPENDENCIES} ${NAMES_GENERATOR} ${SCRIPTS_BINDINGS} ${_attrs} ${_tags}
+ COMMAND ${PERL_EXECUTABLE} ${NAMES_GENERATOR} --preprocessor "${CODE_GENERATOR_PREPROCESSOR_WITH_LINEMARKERS}" --outputDir ${DERIVED_SOURCES_WEBCORE_DIR} ${_arguments} ${_additionArguments}
+ VERBATIM)
+endmacro()
+
+macro(MAKE_HASH_TOOLS _source)
+ get_filename_component(_name ${_source} NAME_WE)
+
+ if (${_source} STREQUAL "DocTypeStrings")
+ set(_hash_tools_h "${DERIVED_SOURCES_WEBCORE_DIR}/HashTools.h")
+ else ()
+ set(_hash_tools_h "")
+ endif ()
+
+ add_custom_command(
+ OUTPUT ${DERIVED_SOURCES_WEBCORE_DIR}/${_name}.cpp ${_hash_tools_h}
+ MAIN_DEPENDENCY ${_source}.gperf
+ COMMAND ${PERL_EXECUTABLE} ${WEBCORE_DIR}/make-hash-tools.pl ${DERIVED_SOURCES_WEBCORE_DIR} ${_source}.gperf ${GPERF_EXECUTABLE}
+ VERBATIM)
+
+ unset(_name)
+ unset(_hash_tools_h)
+endmacro()
+
+macro(WEEX_WRAP_SOURCELIST)
+ foreach (_file ${ARGN})
+ get_filename_component(_basename ${_file} NAME_WE)
+ get_filename_component(_path ${_file} PATH)
+
+ if (NOT _file MATCHES "${DERIVED_SOURCES_WEBCORE_DIR}")
+ string(REGEX REPLACE "/" "\\\\\\\\" _sourcegroup "${_path}")
+ source_group("${_sourcegroup}" FILES ${_file})
+ endif ()
+ endforeach ()
+
+ source_group("DerivedSources" REGULAR_EXPRESSION "${DERIVED_SOURCES_WEBCORE_DIR}")
+endmacro()
+
+macro(WEEX_FRAMEWORK _target)
+ include_directories(SYSTEM ${${_target}_SYSTEM_INCLUDE_DIRECTORIES})
+ add_library(${_target} ${${_target}_LIBRARY_TYPE}
+ ${${_target}_HEADERS}
+ ${${_target}_SOURCES}
+ )
+ target_include_directories(${_target} PUBLIC "$<BUILD_INTERFACE:${${_target}_INCLUDE_DIRECTORIES}>")
+ target_link_libraries(${_target} ${${_target}_LIBRARIES})
+ set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS "BUILDING_${_target}")
+ target_compile_definitions(${_target} PRIVATE "${${_target}_DEFINITIONS}")
+
+ if (${_target}_OUTPUT_NAME)
+ set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${${_target}_OUTPUT_NAME})
+ endif ()
+
+ if (${_target}_PRE_BUILD_COMMAND)
+ add_custom_target(_${_target}_PreBuild COMMAND ${${_target}_PRE_BUILD_COMMAND} VERBATIM)
+ add_dependencies(${_target} _${_target}_PreBuild)
+ endif ()
+
+ if (${_target}_POST_BUILD_COMMAND)
+ add_custom_command(TARGET ${_target} POST_BUILD COMMAND ${${_target}_POST_BUILD_COMMAND} VERBATIM)
+ endif ()
+
+# if (APPLE AND NOT PORT STREQUAL "GTK" AND NOT ${${_target}_LIBRARY_TYPE} MATCHES STATIC)
+# set_target_properties(${_target} PROPERTIES FRAMEWORK TRUE)
+# install(TARGETS ${_target} FRAMEWORK DESTINATION ${LIB_INSTALL_DIR})
+# endif ()
+endmacro()
+
+macro(WEEX_CREATE_FORWARDING_HEADER _target_directory _file)
+ get_filename_component(_source_path "${CMAKE_SOURCE_DIR}/Source/" ABSOLUTE)
+ get_filename_component(_absolute "${_file}" ABSOLUTE)
+ get_filename_component(_name "${_file}" NAME)
+ set(_target_filename "${_target_directory}/${_name}")
+
+ # Try to make the path in the forwarding header relative to the Source directory
+ # so that these forwarding headers are compatible with the ones created by the
+ # WebKit2 generate-forwarding-headers script.
+ string(REGEX REPLACE "${_source_path}/" "" _relative ${_absolute})
+
+ set(_content "#include \"${_relative}\"\n")
+
+ if (EXISTS "${_target_filename}")
+ file(READ "${_target_filename}" _old_content)
+ endif ()
+
+ if (NOT _old_content STREQUAL _content)
+ file(WRITE "${_target_filename}" "${_content}")
+ endif ()
+endmacro()
+
+macro(WEEX_CREATE_FORWARDING_HEADERS _framework)
+ # On Windows, we copy the entire contents of forwarding headers.
+ if (NOT WIN32)
+ set(_processing_directories 0)
+ set(_processing_files 0)
+ set(_target_directory "${DERIVED_SOURCES_DIR}/ForwardingHeaders/${_framework}")
+
+ file(GLOB _files "${_target_directory}/*.h")
+ foreach (_file ${_files})
+ file(READ "${_file}" _content)
+ string(REGEX MATCH "^#include \"([^\"]*)\"" _matched ${_content})
+ if (_matched AND NOT EXISTS "${CMAKE_SOURCE_DIR}/Source/${CMAKE_MATCH_1}")
+ file(REMOVE "${_file}")
+ endif ()
+ endforeach ()
+
+ foreach (_currentArg ${ARGN})
+ if ("${_currentArg}" STREQUAL "DIRECTORIES")
+ set(_processing_directories 1)
+ set(_processing_files 0)
+ elseif ("${_currentArg}" STREQUAL "FILES")
+ set(_processing_directories 0)
+ set(_processing_files 1)
+ elseif (_processing_directories)
+ file(GLOB _files "${_currentArg}/*.h")
+ foreach (_file ${_files})
+ WEEX_CREATE_FORWARDING_HEADER(${_target_directory} ${_file})
+ endforeach ()
+ elseif (_processing_files)
+ WEEX_CREATE_FORWARDING_HEADER(${_target_directory} ${_currentArg})
+ endif ()
+ endforeach ()
+ endif ()
+endmacro()
+
+# Helper macro which wraps generate-message-receiver.py and generate-message-header.py scripts
+# _output_source is a list name which will contain generated sources.(eg. WebKit2_SOURCES)
+# _input_files are messages.in files to generate.
+macro(GENERATE_WEEX2_MESSAGE_SOURCES _output_source _input_files)
+ foreach (_file ${_input_files})
+ get_filename_component(_name ${_file} NAME_WE)
+ add_custom_command(
+ OUTPUT ${DERIVED_SOURCES_WEEX2_DIR}/${_name}MessageReceiver.cpp ${DERIVED_SOURCES_WEEX2_DIR}/${_name}Messages.h
+ MAIN_DEPENDENCY ${_file}
+ DEPENDS ${WEEX2_DIR}/Scripts/webkit/__init__.py
+ ${WEEX2_DIR}/Scripts/webkit/messages.py
+ ${WEEX2_DIR}/Scripts/webkit/model.py
+ ${WEEX2_DIR}/Scripts/webkit/parser.py
+ COMMAND ${PYTHON_EXECUTABLE} ${WEEX2_DIR}/Scripts/generate-message-receiver.py ${_file} > ${DERIVED_SOURCES_WEEX2_DIR}/${_name}MessageReceiver.cpp
+ COMMAND ${PYTHON_EXECUTABLE} ${WEEX2_DIR}/Scripts/generate-messages-header.py ${_file} > ${DERIVED_SOURCES_WEEX2_DIR}/${_name}Messages.h
+ WORKING_DIRECTORY ${WEEX2_DIR}
+ VERBATIM)
+
+ list(APPEND ${_output_source} ${DERIVED_SOURCES_WEEX2_DIR}/${_name}MessageReceiver.cpp)
+ endforeach ()
+endmacro()
+
+macro(MAKE_JS_FILE_ARRAYS _output_cpp _output_h _scripts _scripts_dependencies)
+ if (NOT CMAKE_VERSION VERSION_LESS 3.1)
+ set(_python_path ${CMAKE_COMMAND} -E env "PYTHONPATH=${JavaScriptCore_SCRIPTS_DIR}")
+ elseif (WIN32)
+ set(_python_path set "PYTHONPATH=${JavaScriptCore_SCRIPTS_DIR}" &&)
+ else ()
+ set(_python_path "PYTHONPATH=${JavaScriptCore_SCRIPTS_DIR}")
+ endif ()
+
+ add_custom_command(
+ OUTPUT ${_output_h} ${_output_cpp}
+ MAIN_DEPENDENCY ${WEBCORE_DIR}/Scripts/make-js-file-arrays.py
+ DEPENDS ${${_scripts}}
+ COMMAND ${_python_path} ${PYTHON_EXECUTABLE} ${WEBCORE_DIR}/Scripts/make-js-file-arrays.py ${_output_h} ${_output_cpp} ${${_scripts}}
+ VERBATIM)
+ list(APPEND WebCore_DERIVED_SOURCES ${_output_cpp})
+ ADD_SOURCE_DEPENDENCIES(${${_scripts_dependencies}} ${_output_h} ${_output_cpp})
+endmacro()
+
+# Helper macro for using all-in-one builds
+# This macro removes the sources included in the _all_in_one_file from the input _file_list.
+# _file_list is a list of source files
+# _all_in_one_file is an all-in-one cpp file includes other cpp files
+# _result_file_list is the output file list
+macro(PROCESS_ALLINONE_FILE _file_list _all_in_one_file _result_file_list _no_compile)
+ file(STRINGS ${_all_in_one_file} _all_in_one_file_content)
+ set(${_result_file_list} ${_file_list})
+ set(_allins "")
+ foreach (_line ${_all_in_one_file_content})
+ string(REGEX MATCH "^#include [\"<](.*)[\">]" _found ${_line})
+ if (_found)
+ list(APPEND _allins ${CMAKE_MATCH_1})
+ endif ()
+ endforeach ()
+
+ foreach (_allin ${_allins})
+ if (${_no_compile})
+ # For DerivedSources.cpp, we still need the derived sources to be generated, but we do not want them to be compiled
+ # individually. We add the header to the result file list so that CMake knows to keep generating the files.
+ string(REGEX REPLACE "(.*)\\.cpp" "\\1" _allin_no_ext ${_allin})
+ string(REGEX REPLACE ";([^;]*/)${_allin_no_ext}\\.cpp;" ";\\1${_allin_no_ext}.h;" _new_result "${${_result_file_list}};")
+ else ()
+ string(REGEX REPLACE ";[^;]*/${_allin};" ";" _new_result "${${_result_file_list}};")
+ endif ()
+ set(${_result_file_list} ${_new_result})
+ endforeach ()
+
+endmacro()
+
+# Helper macros for debugging CMake problems.
+macro(WEEX_DEBUG_DUMP_COMMANDS)
+ set(CMAKE_VERBOSE_MAKEFILE ON)
+endmacro()
+
+macro(WEEX_DEBUG_DUMP_VARIABLES)
+ set_cmake_property(_variableNames VARIABLES)
+ foreach (_variableName ${_variableNames})
+ message(STATUS "${_variableName}=${${_variableName}}")
+ endforeach ()
+endmacro()
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/CMakeLists.txt b/weex_core/Source/android/jsengine/dependence/bmalloc/CMakeLists.txt
new file mode 100644
index 0000000000..a0bc3da66a
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/CMakeLists.txt
@@ -0,0 +1,38 @@
+include(WebKitCommon)
+set_property(DIRECTORY . PROPERTY FOLDER "bmalloc")
+
+set(bmalloc_INCLUDE_DIRECTORIES
+ "${BMALLOC_DIR}"
+)
+
+set(bmalloc_SOURCES
+ bmalloc/Allocator.cpp
+ bmalloc/AvailableMemory.cpp
+ bmalloc/Cache.cpp
+ bmalloc/Deallocator.cpp
+ bmalloc/DebugHeap.cpp
+ bmalloc/Environment.cpp
+ bmalloc/Heap.cpp
+ bmalloc/LargeMap.cpp
+ bmalloc/Logging.cpp
+ bmalloc/ObjectType.cpp
+ bmalloc/StaticMutex.cpp
+ bmalloc/VMHeap.cpp
+ bmalloc/mbmalloc.cpp
+)
+
+if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
+ list(APPEND bmalloc_SOURCES
+ bmalloc/Zone.cpp
+ )
+endif ()
+
+set(bmalloc_LIBRARIES
+ ${CMAKE_DL_LIBS}
+)
+
+WEBKIT_WRAP_SOURCELIST(${bmalloc_SOURCES})
+include_directories(${bmalloc_INCLUDE_DIRECTORIES})
+add_library(bmalloc STATIC ${bmalloc_SOURCES})
+target_link_libraries(bmalloc ${bmalloc_LIBRARIES})
+set_target_properties(bmalloc PROPERTIES COMPILE_DEFINITIONS "BUILDING_bmalloc")
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/ChangeLog b/weex_core/Source/android/jsengine/dependence/bmalloc/ChangeLog
new file mode 100644
index 0000000000..92485e38b4
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/ChangeLog
@@ -0,0 +1,6450 @@
+2017-05-28 Dan Bernstein <mi...@apple.com>
+
+ [Xcode] ALWAYS_SEARCH_USER_PATHS is set to YES
+ https://bugs.webkit.org/show_bug.cgi?id=172691
+
+ Reviewed by Tim Horton.
+
+ * Configurations/Base.xcconfig: Set ALWAYS_SEARCH_USER_PATHS to NO.
+
+2017-05-25 Geoffrey Garen <gg...@apple.com> and Michael Saboff <ms...@apple.com>
+
+ bmalloc: scavenger runs too much on JetStream
+ https://bugs.webkit.org/show_bug.cgi?id=172373
+
+ Reviewed by Geoffrey Garen.
+
+ Instruments says that JetStream on macOS spends about 3% of its time in
+ madvise.
+
+ In <https://bugs.webkit.org/show_bug.cgi?id=160098>, Ben saw some
+ evidence that madvise was the reason that switching to bmalloc for
+ DFG::Node allocations was a slowdown the first time around.
+
+ In <https://bugs.webkit.org/show_bug.cgi?id=172124>, Michael saw that
+ scavening policy can affect JetStream.
+
+ Intuitively, it seems wrong for the heap to idle shrink during hardcore
+ benchmarking.
+
+ The strategy here is to back off in response to any heap growth event,
+ and to wait 2s instead of 0.5s for heap growth to take place -- but we
+ scavenge immediately in response to critical memory pressure, to avoid
+ jetsam.
+
+ One hole in this strategy is that a workload with a perfectly
+ unfragmented heap that allocates and deallocates ~16kB every 2s will
+ never shrink its heap. This doesn't seem to be a problem in practice.
+
+ This looks like a 2% - 4% speedup on JetStream on Mac Pro and MacBook Air.
+
+ * bmalloc/AsyncTask.h:
+ (bmalloc::AsyncTask::willRun):
+ (bmalloc::AsyncTask::willRunSoon):
+ (bmalloc::Function>::AsyncTask):
+ (bmalloc::Function>::run):
+ (bmalloc::Function>::runSoon):
+ (bmalloc::Function>::threadRunLoop):
+ (bmalloc::Function>::runSlowCase): Deleted. Added a "run soon" state
+ so that execution delay is modeled directly instead of implicitly
+ through sleep events. This enables the Heap to issue a "run now" event
+ at any moment in response ot memory pressure.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap): Don't call into our own API -- that's a layering
+ violation.
+
+ (bmalloc::Heap::updateMemoryInUseParameters): No need for
+ m_scavengeSleepDuration anymore.
+
+ (bmalloc::Heap::concurrentScavenge): Added a back-off policy when the
+ heap is growing.
+ (bmalloc::Heap::scavenge):
+
+ (bmalloc::Heap::scavengeSmallPages):
+ (bmalloc::Heap::scavengeLargeObjects): Don't try to give up in the middle
+ of a scavenge event. Our new backoff policy supplants that design. Also,
+ it's easier to profile and understand scavenging behavior if it always
+ runs to completion once started.
+
+ (bmalloc::Heap::scheduleScavenger):
+ (bmalloc::Heap::scheduleScavengerIfUnderMemoryPressure): Added a
+ synchronous amortized check for memory pressure. This check has the
+ benefit that it runs immediately during high rates of heap activity,
+ so we can detect memory pressure right away and wake the scavenger
+ instead of waiting for the scavenger to wake up.
+
+ (bmalloc::Heap::allocateSmallPage):
+ (bmalloc::Heap::deallocateSmallLine):
+ (bmalloc::Heap::splitAndAllocate):
+ (bmalloc::Heap::tryAllocateLarge):
+ (bmalloc::Heap::shrinkLarge):
+ (bmalloc::Heap::deallocateLarge):
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::isUnderMemoryPressure):
+ * bmalloc/Sizes.h:
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::deallocateSmallPage):
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::scavenge): Updated for API changes above.
+
+2017-05-17 Michael Saboff <ms...@apple.com>
+
+ [iOS] The Garbage Collector shouldn't rely on the bmalloc scavenger for up to date memory footprint info (172186)
+ https://bugs.webkit.org/show_bug.cgi?id=172186
+
+ Reviewed by Geoffrey Garen.
+
+ The calls memoryFootprint() and percentAvailableMemoryInUse() now make a system call to get
+ the current memory footprint value.
+
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::memoryFootprint):
+ (bmalloc::Heap::percentAvailableMemoryInUse):
+
+2017-05-16 Michael Saboff <ms...@apple.com>
+
+ REGRESSION(r216763): JetStream is 1% slower on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=172124
+
+ Reviewed by Filip Pizlo.
+
+ It appears that changing maxScavengeSleepDuration from 512 to 250ms in r216763 is
+ responsible for the regression.
+
+ * bmalloc/Sizes.h:
+
+2017-05-15 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Bump the size of the deallocator log to 512
+ https://bugs.webkit.org/show_bug.cgi?id=172143
+
+ Reviewed by Michael Saboff.
+
+ This is a speedup on parallel workloads for machines with lots of CPUs.
+
+ * bmalloc/Sizes.h:
+
+2017-05-12 Michael Saboff <ms...@apple.com>
+
+ [iOS] Use memory footprint to dynamically adjust behavior of allocators
+ https://bugs.webkit.org/show_bug.cgi?id=171944
+
+ Reviewed by Filip Pizlo.
+
+ This change is iOS only.
+
+ After the scavenger thread completes scavenging, it asks the OS for how much total memory the
+ process is using. This information is used to update the sleep delay for the scanvenger thread,
+ as well as to provide memory in use data for other parts of the system.
+
+ The scavenger sleep time is calculated using the following quadradic equation.
+
+ scavengerSleep = 1.2*percentFreeMemory^2 - percentFreeMemory + 2
+
+ Where percentFreeMemory is between 0 and 100. The result is constrained to the values 2 and 250.
+
+ This equation empirically works out to providing a 2ms sleep time when we have less than 10%
+ memory available, 30ms when 20% is available and 250ms when 50% or more is available. In testing,
+ this exponentially agressive scavenging delay by itself reduced memory usage and made it much
+ more deterministic when used without the corresponding change in the JSC Heap.
+
+ Changed the scavenger thread to use the User Initiated QOS priority to ensure it doesn't
+ get starved.
+
+ Moved the non-Windows functionality of WTF::RAMSize() to new files AvailableMemory.{cpp,h}
+ and implemented in the function availableMemory(). That functions limits the value returned
+ on iOS to a maximum of 840MB as that is the jetsam soft memory limit.
+ Added a new API availableMemory() so that WTF::RAMSize() will use this value.
+
+ * CMakeLists.txt:
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/BPlatform.h:
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap):
+ (bmalloc::Heap::updateMemoryInUseParameters):
+ (bmalloc::Heap::concurrentScavenge):
+ (bmalloc::Heap::scavenge):
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::memoryFootprint):
+ (bmalloc::Heap::percentAvailableMemoryInUse):
+ * bmalloc/Sizes.h:
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::availableMemory):
+ (bmalloc::api::memoryFootprint):
+ (bmalloc::api::percentAvailableMemoryInUse):
+ * bmalloc/AvailableMemory.cpp: Added.
+ (bmalloc::computeAvailableMemory):
+ (bmalloc::availableMemory):
+ * bmalloc/AvailableMemory.h: Added.
+
+2017-05-05 Joseph Pecoraro <pe...@apple.com>
+
+ Leaks always reports "WebKit Malloc Memory Pressure Handler" dispatch_queue/source as leaking
+ https://bugs.webkit.org/show_bug.cgi?id=171532
+
+ Reviewed by Geoffrey Garen.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap):
+ * bmalloc/Heap.h:
+ Store the dispatch_source_t in a member to avoid a false positive leak.
+
+2017-04-27 Michael Saboff <ms...@apple.com>
+
+ bmalloc scavenger should know what page classes are allocating
+ https://bugs.webkit.org/show_bug.cgi?id=171384
+
+ Reviewed by Geoffrey Garen.
+
+ This change replaces m_isAllocatingPages with a per page class flag to track which page
+ classes are currently allocating. When scavenging, we skip page classes that are actively
+ allocating and come back to them on a subsequent pass. This reduces the amount of time it
+ takes for scavenger to free up pages as well as the total time it takes to handle all
+ page classes.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap):
+ (bmalloc::Heap::concurrentScavenge):
+ (bmalloc::Heap::scavenge):
+ (bmalloc::Heap::scavengeSmallPages):
+ (bmalloc::Heap::scavengeLargeObjects):
+ (bmalloc::Heap::allocateSmallPage):
+ (bmalloc::Heap::splitAndAllocate):
+ (bmalloc::Heap::deallocateLarge):
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::takeRequestedScavengerThreadQOSClass): Deleted.
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::deallocateSmallPage):
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::scavenge):
+
+2017-04-25 Michael Saboff <ms...@apple.com>
+
+ Call bmalloc scavenger first when handling a memory pressure event
+ https://bugs.webkit.org/show_bug.cgi?id=171289
+
+ Reviewed by Geoffrey Garen.
+
+ Registered a critical memory pressure handler. We add this handler in addition to the
+ call to release bmalloc memory in the WebCore releaseMemory handler for the case of
+ JSC API users that don't use WebCore. When both handlers are in the process, it is
+ basically a race. One will win, but the loser won't do any more work, so it is harmless.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap):
+
+2017-04-14 Mark Lam <ma...@apple.com>
+
+ Update architectures in xcconfig files.
+ https://bugs.webkit.org/show_bug.cgi?id=170867
+ <rdar://problem/31628104>
+
+ Reviewed by Joseph Pecoraro.
+
+ * Configurations/Base.xcconfig:
+
+2017-04-12 Dan Bernstein <mi...@apple.com>
+
+ [Mac] Future-proof .xcconfig files
+ https://bugs.webkit.org/show_bug.cgi?id=170802
+
+ Reviewed by Tim Horton.
+
+ * Configurations/Base.xcconfig:
+ * Configurations/DebugRelease.xcconfig:
+
+2017-02-03 Ting-Wei Lan <la...@gmail.com>
+
+ Include cstdlib before using ::malloc and posix_memalign
+ https://bugs.webkit.org/show_bug.cgi?id=167800
+
+ Reviewed by Geoffrey Garen.
+
+ * bmalloc/DebugHeap.cpp:
+
+2017-02-01 Andreas Kling <ak...@apple.com>
+
+ Implement the alwaysRunsAtBackgroundPriority WK2 setting using thread QoS.
+ <https://webkit.org/b/167387>
+ <rdar://problem/29711409>
+
+ Reviewed by Antti Koivisto.
+
+ Support changing the QoS level of the scavenger thread asynchronously through
+ a request variable. This is not the most elegant thing in the world, but since
+ threads are only allowed to change their own QoS class, our options are limited.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::concurrentScavenge):
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::takeRequestedScavengerThreadQOSClass):
+ (bmalloc::Heap::setScavengerThreadQOSClass):
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::setScavengerThreadQOSClass):
+
+2017-01-13 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Use a separate zone when using system malloc
+ https://bugs.webkit.org/show_bug.cgi?id=167014
+
+ Reviewed by Filip Pizlo.
+
+ Harris asked for this so he could separate Safari and WebKit memory use
+ when doing memory analysis.
+
+ This patch adds an explicit DebugHeap class that contains all our
+ code for specialized allocation with debugging.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::Allocator):
+ (bmalloc::Allocator::tryAllocate):
+ (bmalloc::Allocator::allocateImpl):
+ (bmalloc::Allocator::reallocate):
+ (bmalloc::Allocator::allocateSlowCase):
+ * bmalloc/Allocator.h: Forward to DebugHeap instead of inlining all the
+ code. This is required for our new interface, and it is also a nice
+ simplification that moves some not-very-important code out of the way.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::Deallocator):
+ (bmalloc::Deallocator::scavenge):
+ (bmalloc::Deallocator::deallocateSlowCase):
+ * bmalloc/Deallocator.h: Ditto.
+
+ * bmalloc/DebugHeap.cpp: Added.
+ (bmalloc::DebugHeap::DebugHeap):
+ (bmalloc::DebugHeap::malloc):
+ (bmalloc::DebugHeap::memalign):
+ (bmalloc::DebugHeap::realloc):
+ (bmalloc::DebugHeap::free):
+ * bmalloc/DebugHeap.h: Added. New class for overriding normal heap
+ behavior. Right now, it just adds a malloc zone and then forwards to
+ system malloc -- but we can add lots more kinds of debug heaps in the
+ future if we find them useful.
+
+ * bmalloc/Environment.cpp:
+ (bmalloc::Environment::Environment):
+ (bmalloc::Environment::computeIsDebugHeapEnabled):
+ (bmalloc::Environment::computeIsBmallocEnabled): Deleted.
+ * bmalloc/Environment.h:
+ (bmalloc::Environment::isDebugHeapEnabled):
+ (bmalloc::Environment::isBmallocEnabled): Deleted. Renamed everything to
+ reflect our new use of DebugHeap.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap):
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::debugHeap): Updated to use DebugHeap.
+ (bmalloc::Heap::environment): Deleted.
+
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::isEnabled): Updated to use DebugHeap.
+
+2016-12-15 Myles C. Maxfield <mm...@apple.com>
+
+ Sort Xcode project files
+ https://bugs.webkit.org/show_bug.cgi?id=165937
+
+ Reviewed by Simon Fraser.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+
+2016-12-08 David Kilzer <dd...@apple.com>
+
+ Always check the return value of pthread_key_create()
+ <https://webkit.org/b/165274>
+
+ Reviewed by Darin Adler.
+
+ * bmalloc/PerThread.h:
+ (bmalloc::PerThreadStorage::init): Call BCRASH() if
+ pthread_key_create() returns an error. The error code will be
+ stored in a register available in a crash log, so no need to log
+ the value explicitly.
+
+2016-12-06 Alexey Proskuryakov <ap...@apple.com>
+
+ Correct SDKROOT values in xcconfig files
+ https://bugs.webkit.org/show_bug.cgi?id=165487
+ rdar://problem/29539209
+
+ Reviewed by Dan Bernstein.
+
+ Fix suggested by Dan Bernstein.
+
+ * Configurations/DebugRelease.xcconfig:
+
+2016-11-29 Andy Estes <ae...@apple.com>
+
+ [Cocoa] Enable two clang warnings recommended by Xcode
+ https://bugs.webkit.org/show_bug.cgi?id=164498
+
+ Reviewed by Mark Lam.
+
+ * Configurations/Base.xcconfig: Enabled CLANG_WARN_INFINITE_RECURSION and CLANG_WARN_SUSPICIOUS_MOVE.
+
+2016-11-10 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc threads should have a non-default QoS
+ https://bugs.webkit.org/show_bug.cgi?id=164612
+
+ Reviewed by Filip Pizlo.
+
+ * bmalloc/AsyncTask.h:
+ (bmalloc::Function>::threadEntryPoint): Request user-interactive quality
+ of service because user-interactive tasks use malloc.
+
+2016-10-20 Mark Lam <ma...@apple.com>
+
+ bmalloc api should crash on failure to allocate when !isBmallocEnabled.
+ https://bugs.webkit.org/show_bug.cgi?id=163766
+
+ Reviewed by Keith Miller and Filip Pizlo.
+
+ We want to crash in bmalloc on failure to allocate even when !isBmallocEnabled.
+ This is so that failures to allocate memory will manifest as crashes with a
+ unique signature (i.e. as a SIGTRAP on release builds, or as a write to illegal
+ address 0xbbadbeef on debug builds) and the crash will manifest inside bmalloc.
+ This distinguishes allocation failures from other crashing bugs that manifest as
+ SIGSEGVs due to random pointer dereferences in the clients of bmalloc.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::allocateImpl):
+ (bmalloc::Allocator::reallocate):
+ (bmalloc::Allocator::allocateSlowCase):
+
+2016-09-26 Yoshiaki Jitsukawa <Yo...@sony.com>
+
+ Avoid implicit conversion from iterator to pointer
+ https://bugs.webkit.org/show_bug.cgi?id=162482
+
+ Reviewed by Geoffrey Garen.
+
+ Not every STL supporting such conversion, we should get a pointer explicitly.
+
+ * bmalloc/Chunk.h:
+ (bmalloc::Chunk::lines):
+ (bmalloc::Chunk::pages):
+ * bmalloc/FixedVector.h:
+ (bmalloc::FixedVector::begin):
+
+2016-08-31 Filip Pizlo <fp...@apple.com>
+
+ Butterflies should be allocated in Auxiliary MarkedSpace instead of CopiedSpace and we should rewrite as much of the GC as needed to make this not a regression
+ https://bugs.webkit.org/show_bug.cgi?id=160125
+
+ Reviewed by Geoffrey Garen and Keith Miller.
+
+ I needed to tryMemalign, so I added such a thing.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::allocate):
+ (bmalloc::Allocator::tryAllocate):
+ (bmalloc::Allocator::allocateImpl):
+ * bmalloc/Allocator.h:
+ * bmalloc/Cache.h:
+ (bmalloc::Cache::tryAllocate):
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::tryMemalign):
+
+2016-08-30 Yusuke Suzuki <ut...@gmail.com>
+
+ Unreviewed, build fix for GCC ports
+
+ std::forward is declared in <utility> header.
+
+ * bmalloc/ScopeExit.h:
+
+2016-08-30 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: speed up the lock slow path
+ https://bugs.webkit.org/show_bug.cgi?id=161058
+
+ Unreviewed roll-in - with regression fixed.
+
+ Revert to using yield() instead of swtch() because very low priority
+ background tasks can cause priority inversion and deadlock. In the
+ network process, that happened with com.apple.WebKit.Cache.Storage.serialBackground.
+
+ Still a big speedup on MallocBench.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/ScopeExit.h: Added.
+ (bmalloc::ScopeExit::ScopeExit):
+ (bmalloc::ScopeExit::~ScopeExit):
+ (bmalloc::makeScopeExit):
+ * bmalloc/StaticMutex.cpp:
+ (bmalloc::StaticMutex::lockSlowCase):
+ * bmalloc/StaticMutex.h:
+ (bmalloc::StaticMutex::init):
+
+2016-08-26 Geoffrey Garen <gg...@apple.com>
+
+ Unreviewed build fix.
+
+ Fix the CMake build.
+
+ * CMakeLists.txt:
+
+2016-08-26 Geoffrey Garen <gg...@apple.com>
+
+ Renamed XLarge* => Large*
+ https://bugs.webkit.org/show_bug.cgi?id=161261
+
+ Reviewed by Andreas Kling.
+
+ XLarge is not a thing anymore: We just have Small and Large.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::splitAndAllocate):
+ (bmalloc::Heap::tryAllocateLarge):
+ (bmalloc::Heap::shrinkLarge):
+ (bmalloc::Heap::deallocateLarge):
+ * bmalloc/Heap.h:
+ * bmalloc/LargeMap.cpp: Copied from Source/bmalloc/bmalloc/XLargeMap.cpp.
+ (bmalloc::LargeMap::remove):
+ (bmalloc::LargeMap::add):
+ (bmalloc::XLargeMap::remove): Deleted.
+ (bmalloc::XLargeMap::add): Deleted.
+ * bmalloc/LargeMap.h: Copied from Source/bmalloc/bmalloc/XLargeMap.h.
+ (bmalloc::LargeMap::ranges):
+ (bmalloc::XLargeMap::ranges): Deleted.
+ * bmalloc/LargeRange.h: Copied from Source/bmalloc/bmalloc/XLargeRange.h.
+ (bmalloc::LargeRange::LargeRange):
+ (bmalloc::LargeRange::operator<):
+ (bmalloc::canMerge):
+ (bmalloc::merge):
+ (bmalloc::LargeRange::split):
+ (bmalloc::XLargeRange::XLargeRange): Deleted.
+ (bmalloc::XLargeRange::operator<): Deleted.
+ (bmalloc::XLargeRange::split): Deleted.
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::tryAllocateLargeChunk):
+ * bmalloc/VMHeap.h:
+ * bmalloc/XLargeMap.cpp: Removed.
+ * bmalloc/XLargeMap.h: Removed.
+ * bmalloc/XLargeRange.h: Removed.
+
+2016-08-26 Gavin Barraclough <ba...@apple.com>
+
+ bmalloc: speed up the lock slow path
+ https://bugs.webkit.org/show_bug.cgi?id=161058
+
+ Unreviewed rollout - this caused regressions <rdar://problem/28026089>.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/ScopeExit.h: Removed.
+ * bmalloc/StaticMutex.cpp:
+ (bmalloc::StaticMutex::lockSlowCase):
+ * bmalloc/StaticMutex.h:
+ (bmalloc::StaticMutex::init):
+ * bmalloc/ThreadSwitch.h: Removed.
+
+2016-08-24 Andreas Kling <ak...@apple.com>
+
+ Add bmalloc::api::isEnabled().
+ <https://webkit.org/b/160534>
+
+ Reviewed by Joseph Pecoraro.
+
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::isEnabled):
+
+2016-08-24 Filip Pizlo <fp...@apple.com>
+
+ Unreviewed, roll out r204901, r204897, r204866, r204856, r204854.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::allocate):
+ (bmalloc::Allocator::tryAllocate): Deleted.
+ (bmalloc::Allocator::allocateImpl): Deleted.
+ * bmalloc/Allocator.h:
+ * bmalloc/Cache.h:
+ (bmalloc::Cache::tryAllocate): Deleted.
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::tryMemalign): Deleted.
+
+2016-08-12 Filip Pizlo <fp...@apple.com>
+
+ Butterflies should be allocated in Auxiliary MarkedSpace instead of CopiedSpace and we should rewrite as much of the GC as needed to make this not a regression
+ https://bugs.webkit.org/show_bug.cgi?id=160125
+
+ Reviewed by Geoffrey Garen.
+
+ I needed to tryMemalign, so I added such a thing.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::allocate):
+ (bmalloc::Allocator::tryAllocate):
+ (bmalloc::Allocator::allocateImpl):
+ (bmalloc::Allocator::reallocate):
+ * bmalloc/Allocator.h:
+ * bmalloc/Cache.h:
+ (bmalloc::Cache::allocate):
+ (bmalloc::Cache::tryAllocate):
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::malloc):
+ (bmalloc::api::tryMemalign):
+ (bmalloc::api::memalign):
+
+2016-08-22 Yusuke Suzuki <ut...@gmail.com>
+
+ Unreviewed, build fix on GCC environment
+ https://bugs.webkit.org/show_bug.cgi?id=161058
+
+ std::forward is declared in <utility> header.
+
+ * bmalloc/ScopeExit.h:
+
+2016-08-22 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: speed up the lock slow path
+ https://bugs.webkit.org/show_bug.cgi?id=161058
+
+ Reviewed by Filip Pizlo.
+
+ It is generally accepted practice that a lock should yield instead of
+ spinning when a lock acquisition fails, to avoid wasting CPU and power.
+
+ There are two problems with this generally accepted practice:
+
+ (1) It's a fallacy that yielding is free. In reality, yielding itself
+ consumes CPU and power -- by performing a syscall, running the OS
+ scheduler, and possibly performing a context switch. (Instruments
+ traces of MallocBench show the cost of yielding.) Therefore, spinning a
+ little to avoid yielding can actually *save* CPU and power.
+
+ (2) std::this_thread_yield() on Darwin is way too aggressive: It not only
+ yields but also depresses your priority to absolute zero for 10ms. A
+ recent PLT trace showed a few spots where the main thread just gave up
+ on loading and rendering a page for 10ms so an unimportant background
+ task could run.
+
+ To correct these problems, this patch adds a little bit of spinning to
+ the bmalloc lock slow path.
+
+ Below are performance results on various CPUs.
+
+ Mac Pro (12 hyperthreaded cores = 24 threads):
+
+ Baseline Patch Δ
+ Execution Time:
+ message_one 173ms 173ms
+ message_many 953ms 927ms ^ 1.03x faster
+ churn --parallel 60ms 41ms ^ 1.46x faster
+ list_allocate --parallel 224ms 143ms ^ 1.57x faster
+ tree_allocate --parallel 1,190ms 758ms ^ 1.57x faster
+ tree_churn --parallel 1,517ms 906ms ^ 1.67x faster
+ facebook --parallel 6,519ms 4,580ms ^ 1.42x faster
+ reddit --parallel 5,097ms 3,411ms ^ 1.49x faster
+ flickr --parallel 4,903ms 3,501ms ^ 1.4x faster
+ theverge --parallel 6,641ms 4,505ms ^ 1.47x faster
+
+ <geometric mean> 1,158ms 832ms ^ 1.39x faster
+ <arithmetic mean> 2,728ms 1,895ms ^ 1.44x faster
+ <harmonic mean> 332ms 240ms ^ 1.38x faster
+
+ MacBook Air (2 hyperthreaded cores = 4 threads):
+
+ Baseline Patch Δ
+ Execution Time:
+ message_one 911ms 907ms ^ 1.0x faster
+ message_many 515ms 513ms ^ 1.0x faster
+ churn --parallel 132ms 134ms ! 1.02x slower
+ list_allocate --parallel 104ms 102ms ^ 1.02x faster
+ tree_allocate --parallel 117ms 111ms ^ 1.05x faster
+ tree_churn --parallel 154ms 151ms ^ 1.02x faster
+ facebook --parallel 719ms 687ms ^ 1.05x faster
+ reddit --parallel 382ms 341ms ^ 1.12x faster
+ flickr --parallel 372ms 345ms ^ 1.08x faster
+ theverge --parallel 489ms 444ms ^ 1.1x faster
+
+ <geometric mean> 299ms 287ms ^ 1.04x faster
+ <arithmetic mean> 390ms 374ms ^ 1.04x faster
+ <harmonic mean> 227ms 220ms ^ 1.03x faster
+
+ iPad (2 cores = 2 threads):
+
+ [ Doesn't run Ruby, so no pretty subtest output. ]
+
+ Baseline Patch Δ
+ Execution Time: 174.14ms 171.5ms ^ 1.02x faster
+
+ * bmalloc.xcodeproj/project.pbxproj:
+
+ * bmalloc/ScopeExit.h: Added. A barebones very wimpy version of
+ WTF::ScopeExit.
+ (bmalloc::ScopeExit::ScopeExit):
+ (bmalloc::ScopeExit::~ScopeExit):
+ (bmalloc::makeScopeExit):
+
+ * bmalloc/StaticMutex.cpp:
+ (bmalloc::StaticMutex::lockSlowCase): Spin before yielding -- that's the
+ speedup. Don't spin if another CPU is already spinning. In theory, more
+ than one spinner accomplishes nothing, and I found that there's a cutoff
+ around 8 or 16 spinners that becomes performance negative on Mac Pro.
+
+ (Note: Another way to accomplish a similar result, if you don't want to
+ use a bit of state in the lock, is to spin for a random duration between
+ 0 and aLot. I tested a version of WTF::WeakRandom with unsynchronized
+ static state and it worked great. But I ultimately opted for the explicit
+ bit because I thought it was clearer.)
+
+ * bmalloc/StaticMutex.h:
+ (bmalloc::StaticMutex::init): Initialize our new bit.
+
+ * bmalloc/ThreadSwitch.h: Added.
+ (bmalloc::threadSwitch): Don't call yield() on Darwin because it's too
+ aggressive. swtch() does what we want: Go run something else, without
+ any other side-effects.
+
+2016-08-03 Geoffrey Garen <gg...@apple.com>
+
+ [bmalloc] Merging of XLargeRanges can leak the upper range
+ https://bugs.webkit.org/show_bug.cgi?id=160403
+
+ Reviewed by Michael Saboff.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::scavengeLargeObjects): Don't use removePhysical().
+ Recorded physical size is a performance optimization. It is not the
+ truth. So it might be zero even if a range contains physical pages.
+
+ Instead, iterate each range in the map unconditionally.
+
+ The map can shrink when we release the lock, so we must clamp our
+ iterator each time through the loop.
+
+ The map can grow when we release the lock, but we don't care because
+ growth restarts the scavenger from the beginning.
+
+ * bmalloc/XLargeMap.cpp:
+ (bmalloc::XLargeMap::removePhysical): Deleted. Not used anymore.
+
+ * bmalloc/XLargeMap.h:
+ (bmalloc::XLargeMap::ranges): Added direct access for the sake of
+ scavengeLargeObjects. (This violates our naming conventions -- I'll do
+ a rename in a follow-up patch.)
+
+2016-07-13 Enrica Casucci <en...@apple.com>
+
+ Update supported platforms in xcconfig files to match the sdk names.
+ https://bugs.webkit.org/show_bug.cgi?id=159728
+
+ Reviewed by Tim Horton.
+
+ * Configurations/Base.xcconfig:
+
+2016-07-11 Geoffrey Garen <gg...@apple.com>
+
+ Crash due to abort() calling libc++.1.dylib: std::__1::thread::detach()
+ https://bugs.webkit.org/show_bug.cgi?id=159655
+
+ Reviewed by Sam Weinig.
+
+ It's not entirely clear what was happening in these crashes, but our
+ use of detach() was 100% forward-looking, so we can just remove it for
+ now.
+
+ This patch removes the ability for the scavenger owner to die before
+ the scavenger thread dies (which was unused) and also removes the
+ ability for the scavenger thread to exit (which was used, but we
+ messed up and did thread joining lazily, so we never got any benefit
+ from thread exit.)
+
+ We can add these features back when we need them, and make them work then.
+
+ * bmalloc/AsyncTask.h:
+ (bmalloc::Function>::AsyncTask): We start out in the running state now
+ because we know that starting our thread will run it.
+
+ (bmalloc::Function>::~AsyncTask): We don't support destruction anymore.
+
+ (bmalloc::Function>::runSlowCase): I removed the Exited state.
+
+ (bmalloc::Function>::threadRunLoop): I removed the Exited and
+ ExitRequested states.
+
+ * bmalloc/Heap.h:
+
+ * bmalloc/VMHeap.h:
+
+2016-06-12 David Kilzer <dd...@apple.com>
+
+ Crash in com.apple.WebKit.WebContent at std::__1::__call_once_proxy<std::__1::tuple<CrashReporterSupportLibrary()::$_0&&> >
+ <https://webkit.org/b/158660>
+ <rdar://problem/25652686>
+
+ Reviewed by Darin Adler.
+
+ * bmalloc/Logging.cpp: Switch to use
+ BSOFT_LINK_PRIVATE_FRAMEWORK() to link
+ CrashReporterSupport.framework.
+ * bmalloc/darwin/BSoftLinking.h:
+ (BSOFT_LINK_PRIVATE_FRAMEWORK): Rename from BSOFT_LINK_FRAMEWORK.
+ Switch to use /System/Library/PrivateFrameworks/.
+
+2016-06-11 David Kilzer <dd...@apple.com>
+
+ Implement logging for RELEASE_BASSERT_WITH_MESSAGE() in BAssert.h
+ <http://webkit.org/b/155992>
+
+ Reviewed by Geoff Garen.
+
+ * bmalloc/BAssert.h:
+ (BLOG_ERROR): Add method to always log error messages.
+ (RELEASE_BASSERT_WITH_MESSAGE): Use BLOG_ERROR() to implement
+ logging in Debug builds.
+ * bmalloc/BPlatform.h:
+ (BPLATFORM_MAC): Add.
+ (BUSE): Add BUSE() macro.
+ (BATTRIBUTE_PRINTF): Add.
+ (BUSE_OS_LOG): Add.
+ * bmalloc/Logging.cpp:
+ (bmalloc::reportAssertionFailureWithMessage): Add. Logs to
+ stderr.
+ * bmalloc/Logging.h:
+ (bmalloc::reportAssertionFailureWithMessage): Add declaration.
+
+2016-06-07 Pranjal Jumde <pj...@apple.com>
+
+ Prevents integer overflow in Vector.h
+ https://bugs.webkit.org/show_bug.cgi?id=158455
+ <rdar://problem/20235469>
+
+ Reviewed by Mark Lam.
+
+ * bmalloc/Vector.h:
+ (bmalloc::Vector<T>::reallocateBuffer):
+
+2016-05-27 Konstantin Tokarev <an...@yandex.ru>
+
+ [cmake] Deduplicated bmalloc/Zone.cpp handling.
+ https://bugs.webkit.org/show_bug.cgi?id=158154
+
+ Reviewed by Alex Christensen.
+
+ File bmalloc/Zone.cpp is required on Darwin irrespectively from what
+ port is being built.
+
+ Also I removed WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS() because it's
+ unlikely that bmalloc will ever need port-specific customizations (as
+ opposed to OS-specific customizations which should be done in
+ CMakeLists.txt).
+
+ * CMakeLists.txt: Added bmalloc/Zone.cpp for Darwin.
+ * PlatformGTK.cmake: Removed.
+ * PlatformMac.cmake: Removed.
+
+2016-05-22 Brady Eidson <be...@apple.com>
+
+ Move to C++14.
+ https://bugs.webkit.org/show_bug.cgi?id=157948
+
+ Reviewed by Michael Catanzaro.
+
+ * Configurations/Base.xcconfig:
+
+2016-05-17 Geoffrey Garen <gg...@apple.com>
+
+ REGRESSION: JetStream crashes on some iPhones
+ https://bugs.webkit.org/show_bug.cgi?id=157814
+
+ Reviewed by Michael Saboff.
+
+ * bmalloc/Sizes.h: Reduce smallMax to 32kB.
+
+ Previous justification for 64kB was:
+
+ * bmalloc/Sizes.h: Upped smallMax to 64kB. Upping to 32kB is pretty
+ reasonable, since sizes between 16kB and 32kB share page sizes. I went
+ all the way up to 64kB because the GC uses 64kB blocks, and also just
+ for extra padding to ensure that large allocations are indeed rare.
+
+ It turns out that the bump to 64kB substantially increases our memory
+ high water mark on JetStream, leading to jetsam crashes. Also, there
+ doesn't seem to be a practical performance problem to putting objects in
+ the (32kB - 64kB) range in the large allocator.
+
+2016-05-16 Geoffrey Garen <gg...@apple.com>
+
+ REGRESSION (200035): changes in "WebKit Malloc" VM regions are causing 'leaks' to spew "Failed to map remote region" messages
+ https://bugs.webkit.org/show_bug.cgi?id=157764
+
+ Reviewed by Gavin Barraclough.
+
+ We need to allow for guard pages and only report unguarded pages to the
+ leaks tool -- otherwise, it will try to remote map our guarded pages,
+ and crash.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::tryAllocateLargeChunk):
+ (bmalloc::VMHeap::allocateSmallChunk): Adopt the new API for reporting
+ a range instead of a Chunk*, and report the unguarded range.
+
+ This also fixes a separate bug -- very large allocations would not
+ fully participate in pointer scanning because they would only report 2MB
+ (chunkSize) in size. This could cause false-positive leak reports.
+
+ * bmalloc/Zone.cpp:
+ (bmalloc::enumerator): Updated to scan ranges instead of fixed-sized
+ Chunk pointers.
+
+ * bmalloc/Zone.h:
+ (bmalloc::Zone::ranges):
+ (bmalloc::Zone::addRange): Store ranges instead of fixed-sized Chunk
+ pointers because our VM ranges have variable sizes -- both due to guard
+ pages and due to large allocations.
+
+ (bmalloc::Zone::chunks): Deleted.
+ (bmalloc::Zone::addChunk): Deleted.
+
+2016-05-10 David Kilzer <dd...@apple.com>
+
+ bmalloc should automatically disable itself when ThreadSanitizer is used
+ <https://webkit.org/b/157527>
+
+ Reviewed by Michael Catanzaro.
+
+ * bmalloc/Environment.cpp:
+ (bmalloc::isASanEnabled): Rename to isSanitizerEnabled.
+ (bmalloc::isSanitizerEnabled): Rename from isASanEnabled. Add
+ support for detecting ThreadSanitizer.
+ (bmalloc::Environment::computeIsBmallocEnabled): Switch from
+ isASanEnabled to isSanitizerEnabled.
+
+2016-05-03 Geoffrey Garen <gg...@apple.com>
+
+ Assertion failure in bmalloc::vmRevokePermissions(void*, unsigned long).
+ https://bugs.webkit.org/show_bug.cgi?id=157047
+
+ Reviewed by Filip Pizlo.
+
+ Renamed roundUpToMultipleOfSloppy => roundUpToMultipleOfNonPowerOfTwo.
+
+ * bmalloc/Algorithm.h:
+ (bmalloc::roundUpToMultipleOfNonPowerOfTwo):
+ (bmalloc::roundUpToMultipleOfSloppy): Deleted.
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::allocateSmallChunk):
+
+2016-05-03 Geoffrey Garen <gg...@apple.com>
+
+ Assertion failure in bmalloc::vmRevokePermissions(void*, unsigned long).
+ https://bugs.webkit.org/show_bug.cgi?id=157047
+
+ Reviewed by Filip Pizlo.
+
+ The previous fix aligned the guard page sizes correctly but forgot to
+ align the guard page start address correctly.
+
+ * bmalloc/Algorithm.h:
+ (bmalloc::roundUpToMultipleOfSloppy): Use a new helper method to round
+ up when not working with a power of two, instead of writing out the
+ math by hand.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::allocateSmallChunk): Make sure to round up the guard
+ page start address in addition to its size. Assert at the very end to
+ try to catch more bugs.
+
+2016-04-27 Geoffrey Garen <gg...@apple.com>
+
+ Assertion failure in bmalloc::vmRevokePermissions(void*, unsigned long).
+ https://bugs.webkit.org/show_bug.cgi?id=157047
+
+ Reviewed by Darin Adler.
+
+ * bmalloc/Chunk.h:
+ (bmalloc::Chunk::Chunk):
+ (bmalloc::Chunk::get):
+ (bmalloc::Chunk::offset):
+ (bmalloc::Chunk::address):
+ (bmalloc::Object::Object):
+ (bmalloc::Object::address):
+ (bmalloc::Object::line):
+ (bmalloc::Chunk::object): Deleted.
+ (bmalloc::Object::begin): Deleted.
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateSmallBumpRangesByObject):
+ * bmalloc/Object.h:
+ (bmalloc::Object::chunk):
+ (bmalloc::Object::offset): Renamed begin() to address() because this is
+ not an iterator.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::allocateSmallChunk): Round up pageSize to a vmPageSize
+ multiple because pageSize might be smaller than vmPageSize, but we
+ think the VM system requires vmPageSize-aligned values.
+
+2016-04-25 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: vm allocations should plant guard pages
+ https://bugs.webkit.org/show_bug.cgi?id=156937
+
+ Rolling back in r199936 with a fix for the memory regression.
+
+2016-04-23 Gavin Barraclough <ba...@apple.com>
+
+ bmalloc: vm allocations should plant guard pages
+ https://bugs.webkit.org/show_bug.cgi?id=156937
+
+ Rolling out - looks like this is memory regression.
+
+ * bmalloc/Object.h:
+ (bmalloc::Object::operator+):
+ (bmalloc::Object::operator<=):
+ (bmalloc::Object::operator-): Deleted.
+ * bmalloc/VMAllocate.h:
+ (bmalloc::vmDeallocate):
+ (bmalloc::vmRevokePermissions): Deleted.
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::allocateSmallChunk):
+
+2016-04-22 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: vm allocations should plant guard pages
+ https://bugs.webkit.org/show_bug.cgi?id=156937
+
+ Reviewed by Michael Saboff.
+
+ * bmalloc/Object.h:
+ (bmalloc::Object::operator-): Added a - helper.
+
+ * bmalloc/VMAllocate.h:
+ (bmalloc::vmRevokePermissions): Added a helper to revoke permissions on
+ a VM region. We use this for guard pages.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::allocateSmallChunk): Add guard pages to the start and
+ end of the chunk.
+
+ Note that we don't guard large chunks becuase we need to be able to merge
+ them. Otherwise, we will run out of virtual addresses.
+
+2016-04-22 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Constify introspect function pointer table
+ https://bugs.webkit.org/show_bug.cgi?id=156936
+
+ Reviewed by Michael Saboff.
+
+ * bmalloc/Zone.cpp:
+ (bmalloc::Zone::Zone): Declaring this function pointer table const puts
+ it in the read-only section of the binary, providing a little hardening
+ against overwriting the function pointers at runtime. (We have to
+ const_cast when assigning because the API declares a pointer to non-const,
+ but we happen to know it will never try to write through that pointer.
+ This is not my favorite API.)
+
+2016-04-19 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: fix up overflow checks
+ https://bugs.webkit.org/show_bug.cgi?id=156780
+
+ Reviewed by Mark Lam.
+
+ We used to try to avoid overflow in large object math by setting a very
+ high limit on the largest large object. But that's a bit error-prone
+ since the check is far away from the math that might overflow -- and
+ we were missing some cases.
+
+ This patch removes the limit and instead checks at each math site.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::tryAllocate):
+ (bmalloc::Allocator::allocate):
+ (bmalloc::Allocator::reallocate):
+ (bmalloc::Allocator::allocateSlowCase): Remove the limit. tryAllocateLarge
+ will check for overflow for us.
+
+ * bmalloc/Chunk.h: This ASSERT was just totally wrong.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::tryAllocateLarge): Check for overflow when adding.
+
+ * bmalloc/Sizes.h:
+
+ * bmalloc/VMAllocate.h:
+ (bmalloc::tryVMAllocate): Check for overflow when adding.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::tryAllocateLargeChunk): Check for overflow when adding.
+
+2016-04-19 Geoffrey Garen <gg...@apple.com>
+
+ Unreviewed, try to fix an ASSERT seen on the bots.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::tryAllocateLarge): This ASSERT is supposed to be about
+ alignment, not size. Oops.
+
+2016-04-19 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Merge the large and xlarge allocators
+ https://bugs.webkit.org/show_bug.cgi?id=156734
+
+ Reviewed by Andreas Kling.
+
+ This give us better defense against worst case memory usage:
+
+ Baseline Patch Δ
+ Peak Memory:
+ nimlang 198,132kB 181,468kB ^ 1.09x smaller
+
+ It also eliminates inline metadata for large objects, fixing the
+ regression introduced in r198675, and more:
+
+ run-malloc-benchmarks Baseline:~/OpenSource/WebKitBuildBaseline/Release/ Patch:~/OpenSource/WebKitBuild/Release/
+
+ Baseline Patch Δ
+ Memory at End:
+ big 10,880kB 3,328kB ^ 3.27x smaller
+ facebook 3,112kB 2,868kB ^ 1.09x smaller
+ fragment --parallel 1,848kB 760kB ^ 2.43x smaller
+ fragment_iterate --parallel 4,908kB 776kB ^ 6.32x smaller
+ big --parallel 48,076kB 11,892kB ^ 4.04x smaller
+
+ Overall memory use looks OK:
+
+ run-malloc-benchmarks --memory_warning Baseline:~/OpenSource/WebKitBuildBaseline/Release/ Patch:~/OpenSource/WebKitBuild/Release/
+
+ Baseline Patch Δ
+ Memory at End:
+ <arithmetic mean> 13,992kB 13,987kB ^ 1.0x smaller
+
+ Overall throughput looks OK:
+
+ run-malloc-benchmarks Baseline:~/OpenSource/WebKitBuildBaseline/Release/ Patch:~/OpenSource/WebKitBuild/Release/
+
+ Baseline Patch Δ
+ Execution Time:
+ <arithmetic mean> 103ms 104ms ! 1.01x slower
+
+ We're a bit slower on the "all-out large allocations on all cores"
+ benchmark, but I think that's an OK price to pay:
+
+ Baseline Patch Δ
+ Execution Time:
+ big --parallel 125ms 136ms ! 1.09x slower
+
+ This patch net removes 1.5k lines of code. It turns out that large
+ allocations are rare, and free memory fragments are also rare, so the
+ combination is super rare, and a simple O(n) algorithm that ensures good
+ memory behavior is the best option.
+
+ Fun fact: In practice, the odds that the old code would save memory
+ were *worse* than the odds that it would contain a bug that wasted
+ memory. :)
+
+ * bmalloc.xcodeproj/project.pbxproj:
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::tryAllocate): largeMax is the new xLargeMax since
+ xLargeMax is gone now.
+
+ (bmalloc::Allocator::allocate): I moved the rounding code into allocateLarge,
+ so we don't have to do it here.
+
+ (bmalloc::Allocator::reallocate):
+ (bmalloc::Allocator::allocateSlowCase):
+ (bmalloc::Allocator::allocateXLarge): Deleted. No more XLarge case.
+
+ * bmalloc/Allocator.h:
+
+ * bmalloc/BeginTag.h: Removed.
+ * bmalloc/BoundaryTag.h: Removed.
+
+ * bmalloc/Chunk.h:
+ (bmalloc::ChunkHash::hash): Added a hash function. The best hash function
+ is a unique and monotonically increasing integer, and that's exactly what
+ we typically get from the high bits of a Chunk, since the OS allocates
+ Chunks at unique and increasing addresses.
+ (bmalloc::Chunk::boundaryTags): Deleted.
+ (bmalloc::Chunk::objectType): Deleted.
+ (bmalloc::Chunk::beginTag): Deleted.
+ (bmalloc::Chunk::endTag): Deleted.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::deallocateSlowCase): We no longer know for sure,
+ by looking at its bit pattern, whether a pointer is small or large.
+ Instead, any pointer with large alignment *might* be large, and when
+ we occasionally encounter such an object, we have to consult a hash
+ table in the Heap to find out for sure. This turns out to be just as
+ cheap in practice.
+
+ We don't deallocate large objects on the fast path anymore. We can't,
+ because large objects have out-of-line metadata now.
+
+ (bmalloc::Deallocator::deallocateXLarge): Deleted.
+
+ * bmalloc/Deallocator.h:
+ (bmalloc::Deallocator::deallocateFastCase): See deallocateSlowCase.
+
+ * bmalloc/EndTag.h: Removed.
+ * bmalloc/FreeList.cpp: Removed.
+ * bmalloc/FreeList.h: Removed.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateSmallPage): Be sure to track each chunk in
+ the object type map, so we can distinguish small vs large objects.
+
+ (bmalloc::Heap::deallocateSmallLine): No need to check object type
+ because we know object type now by virtue of being on the small object
+ path.
+
+ (bmalloc::Heap::splitAndAllocate): Be sure to track each chunk in
+ the object type map, so we can distinguish small vs large objects. Large
+ objects can split across chunks, so we need to add each large object's
+ chunk as it is allocated.
+
+ (bmalloc::Heap::tryAllocateLarge):
+ (bmalloc::Heap::allocateLarge):
+ (bmalloc::Heap::isLarge):
+ (bmalloc::Heap::largeSize):
+ (bmalloc::Heap::shrinkLarge):
+ (bmalloc::Heap::deallocateLarge): Merged in existing XLarge logic for
+ large objects.
+
+ (bmalloc::Heap::scavengeXLargeObjects): Deleted.
+ (bmalloc::Heap::allocateXLarge): Deleted.
+ (bmalloc::Heap::tryAllocateXLarge): Deleted.
+ (bmalloc::Heap::xLargeSize): Deleted.
+ (bmalloc::Heap::shrinkXLarge): Deleted.
+ (bmalloc::Heap::deallocateXLarge): Deleted.
+
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::LargeObjectHash::hash):
+
+ * bmalloc/LargeObject.h: Removed.
+
+ * bmalloc/Map.h: Added.
+ (bmalloc::Map::size):
+ (bmalloc::Map::capacity):
+ (bmalloc::Map::get):
+ (bmalloc::Map::set):
+ (bmalloc::Map::remove):
+ (bmalloc::Map::shouldGrow):
+ (bmalloc::Map::shouldShrink):
+ (bmalloc::Map::find):
+ (bmalloc::Hash>::rehash): Simple hash table.
+
+ * bmalloc/Object.h:
+
+ * bmalloc/ObjectType.cpp:
+ (bmalloc::objectType):
+ * bmalloc/ObjectType.h:
+ (bmalloc::mightBeLarge): See deallocateSlowCase.
+ (bmalloc::isXLarge): Deleted.
+
+ * bmalloc/SegregatedFreeList.cpp: Removed.
+ * bmalloc/SegregatedFreeList.h: Removed.
+
+ * bmalloc/Sizes.h: Upped smallMax to 64kB. Upping to 32kB is pretty
+ reasonable, since sizes between 16kB and 32kB share page sizes. I went
+ all the way up to 64kB because the GC uses 64kB blocks, and also just
+ for extra padding to ensure that large allocations are indeed rare.
+
+ * bmalloc/SortedVector.h: Removed.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::tryAllocateLargeChunk):
+ (bmalloc::VMHeap::allocateSmallChunk):
+ (bmalloc::VMHeap::VMHeap): Deleted.
+ (bmalloc::VMHeap::allocateChunk): Deleted.
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::deallocateSmallPage):
+ (bmalloc::VMHeap::allocateLargeObject): Deleted.
+ (bmalloc::VMHeap::deallocateLargeObject): Deleted. Nixed all the boundary
+ tag logic since metadata is out of line now.
+
+ * bmalloc/VMState.h: Removed. Instead of an abstract state, we track
+ the precise amount of committed physical pages at the head of a VM
+ range. This allows us to merge aggressively without triggering an madvise
+ storm most of the time.
+
+ * bmalloc/Vector.h:
+ (bmalloc::Vector<T>::Vector):
+ (bmalloc::Vector<T>::insert):
+ (bmalloc::Vector<T>::remove):
+ (bmalloc::Vector<T>::resize): Filled out some missing helpers.
+
+ * bmalloc/XLargeMap.cpp:
+ (bmalloc::XLargeMap::remove):
+ (bmalloc::XLargeMap::add):
+ (bmalloc::XLargeMap::removePhysical):
+ (bmalloc::XLargeMap::takeFree): Deleted.
+ (bmalloc::XLargeMap::addFree): Deleted.
+ (bmalloc::XLargeMap::addAllocated): Deleted.
+ (bmalloc::XLargeMap::getAllocated): Deleted.
+ (bmalloc::XLargeMap::takeAllocated): Deleted.
+ (bmalloc::XLargeMap::shrinkToFit): Deleted.
+ (bmalloc::XLargeMap::takePhysical): Deleted.
+ (bmalloc::XLargeMap::addVirtual): Deleted.
+ * bmalloc/XLargeMap.h:
+ (bmalloc::XLargeMap::Allocation::operator<): Deleted. We don't track
+ object sizes anymore -- just free space. (The Heap tracks object sizes.)
+ We use plain old linear search for free space. (See intro.)
+
+ * bmalloc/XLargeRange.h:
+ (bmalloc::XLargeRange::physicalSize):
+ (bmalloc::XLargeRange::setPhysicalSize):
+ (bmalloc::merge):
+ (bmalloc::XLargeRange::split):
+ (bmalloc::XLargeRange::vmState): Deleted.
+ (bmalloc::XLargeRange::setVMState): Deleted. See VMState.h.
+
+2016-04-11 Fujii Hironori <Hi...@jp.sony.com>
+
+ [CMake] Make FOLDER property INHERITED
+ https://bugs.webkit.org/show_bug.cgi?id=156460
+
+ Reviewed by Brent Fulgham.
+
+ * CMakeLists.txt:
+ Set FOLDER property as a directory property not a target property
+
+2016-04-08 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: stress_aligned test fails if you increase smallMax
+ https://bugs.webkit.org/show_bug.cgi?id=156414
+
+ Reviewed by Oliver Hunt.
+
+ When size exceeds alignment and is a multiple of alignment and is not
+ a power of two, such as 24kB with 8kB alignment, the small allocator
+ did not always guarantee alignment. Let's fix that.
+
+ * bmalloc/Algorithm.h:
+ (bmalloc::divideRoundingUp): Math is hard.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::allocate): Align to the page size unconditionally.
+ Even if the page size is not a power of two, it might be a multiple of
+ a power of two, and we want alignment to that smaller power of two to
+ be guaranteed.
+
+2016-04-06 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: handle aligned allocations on the fast path
+ https://bugs.webkit.org/show_bug.cgi?id=156302
+
+ Reviewed by Michael Saboff.
+
+ This helps keep the JavaScriptCore GC on the fast path, and it also
+ helps avoid fragmentation on our website stress test:
+
+ nimlang 209,584kB 198,076kB ^ 1.06x smaller
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::allocate): Because we arrange for power-of-two size
+ classes to allocate at power-of-two alignments, we can allocate any
+ small aligned request on the small path.
+
+ * bmalloc/Chunk.h:
+ (bmalloc::Chunk::bytes):
+ (bmalloc::Chunk::lines):
+ (bmalloc::Chunk::pages):
+ (bmalloc::Chunk::boundaryTags):
+ (bmalloc::Chunk::objectType): Moved some code around to provide better
+ API.
+
+ (bmalloc::Chunk::Chunk): Moved this code to VMHeap.
+
+ (bmalloc::Chunk::offset):
+ (bmalloc::Chunk::object): Use our new bytes() helper function.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::allocateChunk): Moved code here from Chunk.
+
+ (bmalloc::VMHeap::allocateSmallChunk): Ensure that power-of-two page
+ sizes always begin allocation at the same alignment. Power-of-two object
+ sizes always request power-of-two page sizes (since that's the least
+ wasteful option), so if we also ensure that power-of-two page sizes get
+ power-of-two alignment, then everything is aligned for all small objects.
+
+2016-04-03 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: segregate small and large objects again, and allocate more objects on the small path
+ https://bugs.webkit.org/show_bug.cgi?id=156152
+
+ Reviewed by Sam Weinig.
+
+ Microbenchmark data suggested that it was a good idea for small and large
+ objects to share memory. But r198675 did not improve memory use in
+ full browser benchmarks.
+
+ This patch reverts to segregating small and large objects -- but without
+ going back to doubled VM usage -- in order to capture a few benefits:
+
+ (*) Small pages fragment the large heap. Separating them out saves a lot
+ of memory in our worst case fragmentation recording:
+
+ nimlang 276,076kB 209,636kB ^ 1.32x smaller
+
+ (*) Small objects are common enough that even their slow paths benefit
+ from simpler code:
+
+ Execution Time:
+ ...
+ facebook 234ms 216ms ^ 1.08x faster
+ reddit 114ms 108ms ^ 1.06x faster
+ flickr 118ms 111ms ^ 1.06x faster
+ theverge 146ms 140ms ^ 1.04x faster
+ ...
+ <arithmetic mean> 107ms 102ms ^ 1.04x faster
+
+ (*) We can use less metadata:
+
+ Memory at End:
+ ...
+ list_allocate 460kB 384kB ^ 1.2x smaller
+ tree_allocate 492kB 424kB ^ 1.16x smaller
+ tree_churn 480kB 404kB ^ 1.19x smaller
+ fragment 532kB 452kB ^ 1.18x smaller
+ fragment_iterate 712kB 588kB ^ 1.21x smaller
+ medium 15,152kB 11,796kB ^ 1.28x smaller
+ big 15,044kB 10,976kB ^ 1.37x smaller
+ ...
+ <arithmetic mean> 7,724kB 7,190kB ^ 1.07x smaller
+
+ This patch also takes advantage of our support for varying the page size
+ at runtime by allocating more objects on the small object path:
+
+ medium 178ms 150ms ^ 1.19x faster
+
+ Some microbenchmarks report memory use increases from this change -- like
+ they reported memory use decreases from r198675 -- but I'm ignoring them
+ for now because I expect our full browser memory benchmarks to confirm
+ that this patch is fine.
+
+ * bmalloc/BumpAllocator.h:
+ (bmalloc::BumpAllocator::BumpAllocator): Use a full unsigned because we
+ can allocate objects larger than 16kB - 1, and a full unsigned does not
+ make BumpAllocator any larger on 64bit systems.
+
+ * bmalloc/Chunk.h:
+ (bmalloc::Chunk::begin):
+ (bmalloc::Chunk::end):
+ (bmalloc::Chunk::size):
+ (bmalloc::Chunk::objectType): Store ObjectType in the Chunk, since it only
+ varies by Chunk now, and not from page to page within a Chunk. Also,
+ union together small and large object metadata, since we will only use
+ one or the other. This saves memory.
+
+ (bmalloc::Chunk::Chunk): Conditionalize initialization based on object
+ type, since only one kind of metadata or the other can be used at runtime.
+
+ (bmalloc::Object::Object):
+ (bmalloc::Object::begin):
+ (bmalloc::SmallPage::end): Deleted.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap):
+ (bmalloc::Heap::initializeLineMetadata): Save a little space, since we
+ know that lines are only 256 bytes long.
+
+ (bmalloc::Heap::initializePageMetadata): Store a dynamic page size for
+ each size class. We used to use only one page size (the system page size)
+ but that limited our ability to allocate objects larger than 1kB on the
+ small object path. Now we can handle any object size we want by storing
+ objects of that size in a custom page size.
+
+ (bmalloc::Heap::concurrentScavenge):
+ (bmalloc::Heap::scavenge):
+ (bmalloc::Heap::scavengeSmallPages): Revert to our old linked list
+ strategy for storing small pages.
+
+ (bmalloc::Heap::splitAndAllocate): Object type is per Chunk now.
+
+ (bmalloc::Heap::allocateLarge): Don't nuke the small page list when
+ allocating a large object because the two don't share memory anymore.
+
+ (bmalloc::Heap::allocateSmallPage): Revert to our old linked list
+ strategy for storing small pages.
+
+ (bmalloc::Heap::deallocateSmallLine): Don't return early in the case
+ where this is the first free object in the page. In the case of large-ish
+ objects, the first free object might also be the last free object,
+ since there's one object per page.
+
+ (bmalloc::Heap::allocateSmallBumpRangesByMetadata): Split out some helper
+ lambdas to make this code clearer.
+
+ (bmalloc::Heap::allocateSmallBumpRangesByObject): Added a fast scan
+ for objects larger than the line size. When multiple objects fit in
+ a single line, it's an optimization to scan a line at a time. But when
+ it's one object per line, or one object per 64 lines, it's better just
+ to scan an object at a time.
+
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::allocateSmallBumpRanges):
+ (bmalloc::Heap::derefSmallLine): Match the changes above.
+
+ * bmalloc/LineMetadata.h: We weren't using all those bits.
+
+ * bmalloc/List.h:
+ (bmalloc::List::remove): Put a removed Node fully back into the default
+ (empty) state it was in before it entered the list. This change is not
+ observable, but it makes things clearer when you're debugging.
+
+ * bmalloc/Object.h:
+ (bmalloc::Object::Object):
+ (bmalloc::Object::chunk):
+ (bmalloc::Object::offset):
+ (bmalloc::Object::operator+):
+ (bmalloc::Object::operator<=): Added some helpers for iterating by object.
+
+ * bmalloc/ObjectType.cpp:
+ (bmalloc::objectType): Updated for API change.
+
+ * bmalloc/Sizes.h:
+ (bmalloc::Sizes::maskObjectSize):
+ (bmalloc::Sizes::objectSize):
+ (bmalloc::Sizes::pageSize): Support more page sizes.
+
+ * bmalloc/SmallPage.h:
+ (bmalloc::SmallPage::SmallPage):
+ (bmalloc::SmallPage::objectType): Deleted.
+ (bmalloc::SmallPage::setObjectType): Deleted.
+ (bmalloc::SmallPage::smallPageCount): Deleted.
+ (bmalloc::SmallPage::setSmallPageCount): Deleted. Object type is per
+ Chunk now, and we can infer page count from size class.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::allocateChunk):
+ (bmalloc::VMHeap::allocateSmallChunk):
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateSmallPage):
+ (bmalloc::VMHeap::deallocateSmallPage):
+ (bmalloc::VMHeap::allocateLargeObject): Support our old behavior of
+ storing free pages in linked lists.
+
+2016-03-29 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: support physical page sizes that don't match the virtual page size (take 2)
+ https://bugs.webkit.org/show_bug.cgi?id=156003
+
+ Reviewed by Andreas Kling.
+
+ This is a memory savings on iOS devices where the virtual page size
+ is 16kB but the physical page size is 4kB.
+
+ Take 1 was a memory regression on 16kB virtual / 16kB physical systems
+ because it used a 4kB page size within a 16kB page size, allowing up to
+ 4 different object types to mix within a physical page. Because objects
+ of the same type tend to deallocate at the same time, mixing objects of
+ different types made pages less likely to become completely empty.
+
+ (Take 1 also had a bug where it used a platform #ifdef that didn't exist.
+ Oops.)
+
+ Take 2 allocates units of SmallPages equal to the physical page size.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap):
+ (bmalloc::Heap::initializeLineMetadata):
+ (bmalloc::Heap::allocateSmallBumpRanges):
+ (bmalloc::Heap::allocateSmallPage):
+ (bmalloc::Heap::allocateLarge):
+ (bmalloc::Heap::splitAndAllocate):
+ (bmalloc::Heap::tryAllocateXLarge):
+ (bmalloc::Heap::shrinkXLarge):
+ * bmalloc/Heap.h: Use the physical page size for our VM operations because
+ we're only concerned with returning physical pages to the OS.
+
+ * bmalloc/VMAllocate.h:
+ (bmalloc::vmPageSize):
+ (bmalloc::vmPageShift):
+ (bmalloc::vmSize):
+ (bmalloc::vmValidate):
+ (bmalloc::vmPageSizePhysical):
+ (bmalloc::vmValidatePhysical):
+ (bmalloc::tryVMAllocate):
+ (bmalloc::vmDeallocatePhysicalPages):
+ (bmalloc::vmAllocatePhysicalPages):
+ (bmalloc::vmDeallocatePhysicalPagesSloppy):
+ (bmalloc::vmAllocatePhysicalPagesSloppy): Use the physical page size.
+
+2016-03-29 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: page size should be configurable at runtime
+ https://bugs.webkit.org/show_bug.cgi?id=155993
+
+ Reviewed by Andreas Kling.
+
+ This is a memory win on 32bit iOS devices, since their page sizes are
+ 4kB and not 16kB.
+
+ It's also a step toward supporting 64bit iOS devices that have a
+ 16kB/4kB virtual/physical page size split.
+
+ * bmalloc/Chunk.h: Align to largeAlignment since 2 * smallMax isn't
+ required by the boundary tag allocator.
+
+ (bmalloc::Chunk::page): Account for the slide when accessing a page.
+ Each SmallPage hashes 4kB of memory. When we want to allocate a region
+ of memory larger than 4kB, we store our metadata in the first SmallPage
+ in the region and we assign a slide to the remaining SmallPages, so
+ they forward to that first SmallPage when accessed.
+
+ NOTE: We could use a less flexible technique that just hashed by
+ vmPageSize() instead of 4kB at runtime, with no slide, but I think we'll
+ be able to use this slide technique to make even more page sizes
+ dynamically at runtime, which should save some memory and simplify
+ the allocator.
+
+ (bmalloc::SmallPage::begin): It's invalid to access a SmallPage with
+ a slide, since such SmallPages do not contain meaningful data.
+
+ (bmalloc::SmallPage::end): Account for smallPageCount when computing
+ the size of a page.
+
+ (bmalloc::Chunk::pageBegin): Deleted.
+ (bmalloc::Chunk::pageEnd): Deleted.
+ (bmalloc::Object::pageBegin): Deleted.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap): Cache vmPageSize because computing it might require
+ a syscall.
+
+ (bmalloc::Heap::initializeLineMetadata): Line metadata is a vector instead
+ of a 2D array because we don't know how much metadata we'll need until
+ we know the page size.
+
+ (bmalloc::Heap::scavengeSmallPage): Be sure to revert the slide when
+ deallocating a page. Otherwise, the next attempt to allocate the page
+ will slide when initializing it, sliding to nowhere.
+
+ (bmalloc::Heap::allocateSmallBumpRanges): Account for vector change to
+ line metadata.
+
+ (bmalloc::Heap::allocateSmallPage): Initialize slide and smallPageCount
+ since they aren't constant anymore.
+
+ (bmalloc::Heap::allocateLarge):
+ (bmalloc::Heap::splitAndAllocate):
+ (bmalloc::Heap::tryAllocateXLarge):
+ (bmalloc::Heap::shrinkXLarge): Adopt dynamic page size.
+
+ * bmalloc/Heap.h:
+
+ * bmalloc/Sizes.h: smallPageSize is no longer equal to the VM page
+ size -- it's just the smallest VM page size we're interested in supporting.
+
+ * bmalloc/SmallPage.h:
+ (bmalloc::SmallPage::slide):
+ (bmalloc::SmallPage::setSlide):
+ (bmalloc::SmallPage::smallPageCount):
+ (bmalloc::SmallPage::setSmallPageCount):
+ (bmalloc::SmallPage::ref):
+ (bmalloc::SmallPage::deref): Support slide and small page count as
+ dynamic values. This doesn't increase metadata size since sizeof(SmallPage)
+ rounds up to alignment anyway.
+
+ * bmalloc/VMAllocate.h:
+ (bmalloc::vmPageSize):
+ (bmalloc::vmPageShift):
+ (bmalloc::vmSize):
+ (bmalloc::vmValidate):
+ (bmalloc::tryVMAllocate):
+ (bmalloc::vmDeallocatePhysicalPagesSloppy):
+ (bmalloc::vmAllocatePhysicalPagesSloppy): Treat page size as a variable.
+
+ * bmalloc/Vector.h:
+ (bmalloc::Vector::initialCapacity):
+ (bmalloc::Vector<T>::insert):
+ (bmalloc::Vector<T>::grow):
+ (bmalloc::Vector<T>::shrink):
+ (bmalloc::Vector<T>::shrinkCapacity):
+ (bmalloc::Vector<T>::growCapacity): Treat page size as a variable.
+
+2016-03-29 David Kilzer <dd...@apple.com>
+
+ bmalloc: add logging for mmap() failures
+ <http://webkit.org/b/155409>
+ <rdar://problem/24568515>
+
+ Reviewed by Saam Barati.
+
+ This patch causes additional logging to be generated on internal
+ iOS builds when mmap() fails. We are trying to track down an
+ issue where the WebContent process runs out of VM address space
+ before it is killed by jetsam.
+
+ * CMakeLists.txt: Add Logging.cpp.
+ * bmalloc.xcodeproj/project.pbxproj: Add new files.
+
+ * bmalloc/BAssert.h:
+ (RELEASE_BASSERT_WITH_MESSAGE): Add macro.
+ * bmalloc/Logging.cpp: Added.
+ (bmalloc::logVMFailure): Implementation.
+ * bmalloc/Logging.h: Added.
+ (bmalloc::logVMFailure): Declaration.
+ * bmalloc/VMAllocate.h:
+ (bmalloc::tryVMAllocate): Call logVMFailure() on mmap() failure.
+ * bmalloc/darwin/BSoftLinking.h: Copied from Source/WebCore/platform/mac/SoftLinking.h.
+
+2016-03-26 Geoffrey Garen <gg...@apple.com>
+
+ Unreviewed, rolling out r198702, r198704.
+
+ Caused a memory regression on PLUM.
+
+ Reverted changeset:
+
+ bmalloc: fix an ASSERT on iOS
+ https://bugs.webkit.org/show_bug.cgi?id=155911
+ http://trac.webkit.org/changeset/198704
+
+ bmalloc: support physical page sizes that don't match the virtual page size
+ https://bugs.webkit.org/show_bug.cgi?id=155898
+ http://trac.webkit.org/changeset/198702
+
+2016-03-25 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: fix an ASSERT on iOS
+ https://bugs.webkit.org/show_bug.cgi?id=155911
+
+ Reviewed by Gavin Barraclough.
+
+ * bmalloc/VMAllocate.h:
+ (bmalloc::vmValidatePhysical): Call through to vmValidatePhysical because
+ the vmValidate function validates virtual sizes rather than physical
+ sizes.
+
+2016-03-25 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: support physical page sizes that don't match the virtual page size
+ https://bugs.webkit.org/show_bug.cgi?id=155898
+
+ Reviewed by Gavin Barraclough.
+
+ This is a memory savings on iOS devices where the virtual page size
+ is 16kB but the physical page size is 4kB.
+
+ * bmalloc/Chunk.h:
+ (bmalloc::Chunk::Chunk): smallPageSize is now unrelated to the OS's
+ page size -- it just reflects the optimal unit of memory to recycle
+ between small objects.
+
+ We only need to round up to largeAlignment because small objects allocate
+ as subsets of large objects now.
+
+ (bmalloc::Chunk::page):
+ (bmalloc::Object::pageBegin):
+ (bmalloc::Object::line): Adopt smallPageSize.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::initializeLineMetadata):
+ (bmalloc::Heap::allocateSmallPage):
+ (bmalloc::Heap::allocateLarge): Adopt smallPageSize.
+
+ (bmalloc::Heap::splitAndAllocate):
+ (bmalloc::Heap::tryAllocateXLarge):
+ (bmalloc::Heap::shrinkXLarge): Adopt vmPageSizePhysical(). We want the
+ physical page size because that's the unit at which the hardware MMU
+ will recycle memory.
+
+ * bmalloc/Sizes.h: Adopt smallPageSize.
+
+ * bmalloc/VMAllocate.h:
+ (bmalloc::vmPageSizePhysical):
+ (bmalloc::vmPageSize): Distinguish between page size, which is the virtual
+ memory page size advertised by the OS, and physical page size, which the
+ true hardware page size.
+
+ (bmalloc::vmSize):
+ (bmalloc::vmValidate):
+ (bmalloc::vmValidatePhysical):
+ (bmalloc::tryVMAllocate):
+ (bmalloc::vmDeallocatePhysicalPages):
+ (bmalloc::vmAllocatePhysicalPages):
+ (bmalloc::vmDeallocatePhysicalPagesSloppy):
+ (bmalloc::vmAllocatePhysicalPagesSloppy): Adopt vmPageSize() and
+ vmPageSizePhyiscal().
+
+ * bmalloc/Vector.h:
+ (bmalloc::Vector::initialCapacity):
+ (bmalloc::Vector<T>::shrink):
+ (bmalloc::Vector<T>::shrinkCapacity):
+ (bmalloc::Vector<T>::growCapacity): Adopt vmPageSize(). We'd prefer to
+ use vmPageSizePhysical() but mmap() doesn't support it.
+
+ * bmalloc/XLargeMap.cpp: #include.
+
+2016-03-25 Geoffrey Garen <gg...@apple.com>
+
+ Unreviewed, rolling in r198679.
+
+ r198679 was just a rename. The regression was caused by r198675 and then
+ fixed in r198693.
+
+ Restored changeset:
+
+ "bmalloc: Renamed LargeChunk => Chunk"
+ https://bugs.webkit.org/show_bug.cgi?id=155894
+ http://trac.webkit.org/changeset/198679
+
+2016-03-25 Geoffrey Garen <gg...@apple.com>
+
+ Unreviewed, try to fix a crash seen on the bots.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::reallocate): We have to take the lock even if we're
+ only reading our own data becuse LargeObject contains validation code
+ that will read our neighbors' data as well.
+
+2016-03-25 Ryan Haddad <ry...@apple.com>
+
+ Unreviewed, rolling out r198679.
+
+ This change caused flaky LayoutTest crashes
+
+ Reverted changeset:
+
+ "bmalloc: Renamed LargeChunk => Chunk"
+ https://bugs.webkit.org/show_bug.cgi?id=155894
+ http://trac.webkit.org/changeset/198679
+
+2016-03-25 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: stress_aligned fails when allocating a zero-sized object with XLarge alignment
+ https://bugs.webkit.org/show_bug.cgi?id=155896
+
+ Reviewed by Andreas Kling.
+
+ We normally filter zero-sized allocations into small allocations, but
+ a zero-sized allocation can sneak through if it requires sufficiently
+ large alignment.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::tryAllocateXLarge): Set a floor on allocation size to
+ catch zero-sized allocations.
+
+2016-03-25 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Renamed LargeChunk => Chunk
+ https://bugs.webkit.org/show_bug.cgi?id=155894
+
+ Reviewed by Michael Saboff.
+
+ A Chunk can contain both small and large objects now.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::allocate):
+ * bmalloc/BoundaryTag.h:
+ (bmalloc::BoundaryTag::isFree):
+ * bmalloc/Chunk.h: Copied from Source/bmalloc/bmalloc/LargeChunk.h.
+ (bmalloc::Chunk::pages):
+ (bmalloc::Chunk::begin):
+ (bmalloc::Chunk::end):
+ (bmalloc::Chunk::Chunk):
+ (bmalloc::Chunk::get):
+ (bmalloc::Chunk::beginTag):
+ (bmalloc::Chunk::endTag):
+ (bmalloc::Chunk::offset):
+ (bmalloc::Chunk::object):
+ (bmalloc::Chunk::page):
+ (bmalloc::Chunk::line):
+ (bmalloc::SmallLine::begin):
+ (bmalloc::SmallPage::begin):
+ (bmalloc::SmallPage::end):
+ (bmalloc::Object::Object):
+ (bmalloc::Object::begin):
+ (bmalloc::LargeChunk::pages): Deleted.
+ (bmalloc::LargeChunk::begin): Deleted.
+ (bmalloc::LargeChunk::end): Deleted.
+ (bmalloc::LargeChunk::LargeChunk): Deleted.
+ (bmalloc::LargeChunk::get): Deleted.
+ (bmalloc::LargeChunk::beginTag): Deleted.
+ (bmalloc::LargeChunk::endTag): Deleted.
+ (bmalloc::LargeChunk::offset): Deleted.
+ (bmalloc::LargeChunk::object): Deleted.
+ (bmalloc::LargeChunk::page): Deleted.
+ (bmalloc::LargeChunk::line): Deleted.
+ * bmalloc/Deallocator.cpp:
+ * bmalloc/FreeList.cpp:
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateLarge):
+ * bmalloc/LargeChunk.h: Removed.
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::LargeObject):
+ (bmalloc::LargeObject::merge):
+ (bmalloc::LargeObject::split):
+ * bmalloc/Object.h:
+ (bmalloc::Object::chunk):
+ * bmalloc/ObjectType.cpp:
+ * bmalloc/Sizes.h:
+ * bmalloc/SmallAllocator.h: Removed.
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::VMHeap):
+ (bmalloc::VMHeap::allocateChunk):
+ (bmalloc::VMHeap::allocateLargeChunk): Deleted.
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateLargeObject):
+ (bmalloc::VMHeap::deallocateLargeObject):
+ * bmalloc/Zone.cpp:
+ (bmalloc::enumerator):
+ * bmalloc/Zone.h:
+ (bmalloc::Zone::chunks):
+ (bmalloc::Zone::addChunk):
+ (bmalloc::Zone::largeChunks): Deleted.
+ (bmalloc::Zone::addLargeChunk): Deleted.
+
+2016-03-24 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: small and large objects should share memory
+ https://bugs.webkit.org/show_bug.cgi?id=155866
+
+ Reviewed by Andreas Kling.
+
+ This patch cuts our VM footprint in half. (VM footprint usually doesn't
+ matter, but on iOS there's an artificial VM limit around 700MB, and if
+ you hit it you jetsam / crash.)
+
+ It's also a step toward honoring the hardware page size at runtime,
+ which will reduce memory usage on iOS.
+
+ This patch is a small improvement in peak memory usage because it allows
+ small and large objects to recycle each other's memory. The tradeoff is
+ that we require more metadata, which causes more memory usage after
+ shrinking down from peak memory usage. In the end, we have some memory
+ wins and some losses, and a small win in the mean on our standard memory
+ benchmarks.
+
+ * bmalloc.xcodeproj/project.pbxproj: Removed SuperChunk.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::reallocate): Adopt a new Heap API for shrinking
+ large objects because it's a little more complicated than it used to be.
+
+ Don't check for equality in the XLarge case because we don't do it in
+ other cases, and it's unlikely that we'll be called for no reason.
+
+ * bmalloc/BumpAllocator.h:
+ (bmalloc::BumpAllocator::allocate): Don't ASSERT isSmall because that's
+ an old concept from when small and large objects were in distinct memory
+ regions.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::deallocateSlowCase): Large objects are not
+ segregated anymore.
+
+ (bmalloc::Deallocator::deallocateLarge): Deleted.
+
+ * bmalloc/Deallocator.h:
+ (bmalloc::Deallocator::deallocateFastCase): Don't ASSERT isSmall(). See
+ above.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::scavenge):
+ (bmalloc::Heap::scavengeSmallPage):
+ (bmalloc::Heap::scavengeSmallPages): New helpers for returning cached
+ small pages to the large object heap.
+
+ (bmalloc::Heap::allocateSmallPage): Allocate small pages from the large
+ object heap. This is how we accomplish sharing.
+
+ (bmalloc::Heap::deallocateSmallLine): Handle large objects since we can
+ encounter them on this code path now.
+
+ (bmalloc::Heap::splitAndAllocate): Fixed a bug where we would sometimes
+ not split even though we could.
+
+ Allocating a large object also requires ref'ing its small line so that
+ we can alias memory between small and large objects.
+
+ (bmalloc::Heap::allocateLarge): Return cached small pages before
+ allocating a large object that would fit in a cached small page. This
+ allows some large allocations to reuse small object memory.
+
+ (bmalloc::Heap::shrinkLarge): New helper.
+
+ (bmalloc::Heap::deallocateLarge): Deleted.
+
+ * bmalloc/Heap.h:
+
+ * bmalloc/LargeChunk.h:
+ (bmalloc::LargeChunk::pageBegin):
+ (bmalloc::LargeChunk::pageEnd):
+ (bmalloc::LargeChunk::lines):
+ (bmalloc::LargeChunk::pages):
+ (bmalloc::LargeChunk::begin):
+ (bmalloc::LargeChunk::end):
+ (bmalloc::LargeChunk::LargeChunk):
+ (bmalloc::LargeChunk::get):
+ (bmalloc::LargeChunk::endTag):
+ (bmalloc::LargeChunk::offset):
+ (bmalloc::LargeChunk::object):
+ (bmalloc::LargeChunk::page):
+ (bmalloc::LargeChunk::line):
+ (bmalloc::SmallLine::begin):
+ (bmalloc::SmallLine::end):
+ (bmalloc::SmallPage::begin):
+ (bmalloc::SmallPage::end):
+ (bmalloc::Object::Object):
+ (bmalloc::Object::begin):
+ (bmalloc::Object::pageBegin):
+ (bmalloc::Object::line):
+ (bmalloc::Object::page): I merged all the SmallChunk metadata and code
+ into LargeChunk. Now we use a single class to track both small and large
+ metadata, so we can share memory between small and large objects.
+
+ I'm going to rename this class to Chunk in a follow-up patch.
+
+ * bmalloc/Object.h:
+ (bmalloc::Object::chunk): Updated for LargeChunk transition.
+
+ * bmalloc/ObjectType.cpp:
+ (bmalloc::objectType):
+ * bmalloc/ObjectType.h:
+ (bmalloc::isXLarge):
+ (bmalloc::isSmall): Deleted. The difference between small and large
+ objects is now stored in metadata and is not a property of their
+ virtual address range.
+
+ * bmalloc/SegregatedFreeList.h: One more entry because we cover all of
+ what used to be the super chunk in a large chunk now.
+
+ * bmalloc/Sizes.h: Removed bit masking helpers because we don't use
+ address masks to distinguish small vs large object type anymore.
+
+ * bmalloc/SmallChunk.h: Removed.
+
+ * bmalloc/SmallPage.h:
+ (bmalloc::SmallPage::SmallPage): Store object type per page because any
+ given page can be used for large objects or small objects.
+
+ * bmalloc/SuperChunk.h: Removed.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::VMHeap):
+ (bmalloc::VMHeap::allocateLargeChunk):
+ (bmalloc::VMHeap::allocateSmallChunk): Deleted.
+ (bmalloc::VMHeap::allocateSuperChunk): Deleted.
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateLargeObject):
+ (bmalloc::VMHeap::deallocateLargeObject):
+ (bmalloc::VMHeap::allocateSmallPage): Deleted.
+ (bmalloc::VMHeap::deallocateSmallPage): Deleted. Removed super chunk and
+ small chunk support.
+
+ * bmalloc/Zone.cpp:
+ (bmalloc::enumerator):
+ * bmalloc/Zone.h:
+ (bmalloc::Zone::largeChunks):
+ (bmalloc::Zone::addLargeChunk):
+ (bmalloc::Zone::superChunks): Deleted.
+ (bmalloc::Zone::addSuperChunk): Deleted. Removed super chunk and
+ small chunk support.
+
+2016-03-23 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Added an Object helper class
+ https://bugs.webkit.org/show_bug.cgi?id=155818
+
+ Reviewed by Gavin Barraclough.
+
+ Object is an abstraction that breaks out a void* into its component
+ metadata pointers.
+
+ This is slightly faster than recomputing them, and it enables a future
+ patch in which Object will tell us whether it is small or large.
+
+ * bmalloc.xcodeproj/project.pbxproj: Added to the project.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::reallocate): Use Object to compute size.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::processObjectLog):
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateSmallPage):
+ (bmalloc::Heap::deallocateSmallLine):
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::derefSmallLine): Use Object to deallocate.
+
+ * bmalloc/Object.h: Added.
+ (bmalloc::Object::Object):
+ (bmalloc::Object::chunk):
+ (bmalloc::Object::line):
+ (bmalloc::Object::page): Helper class to break out a void* into its
+ component metadata pointers.
+
+ * bmalloc/SmallChunk.h:
+ (bmalloc::SmallChunk::SmallChunk): SmallPage::get doesn't exist anymore
+ so we use our new helper functions instead.
+
+ (bmalloc::SmallChunk::offset):
+ (bmalloc::SmallChunk::object):
+ (bmalloc::SmallChunk::page):
+ (bmalloc::SmallChunk::line):
+ (bmalloc::SmallLine::begin):
+ (bmalloc::SmallLine::end):
+ (bmalloc::SmallPage::begin): New helpers that operate on the data
+ stored in Object.
+
+ (bmalloc::SmallLine::get): Deleted.
+ (bmalloc::SmallPage::get): Deleted.
+
+ * bmalloc/SmallLine.h:
+ (bmalloc::SmallLine::refCount): Added a default ref value for convenience.
+
+ * bmalloc/SmallPage.h:
+ (bmalloc::SmallPage::SmallPage):
+
+2016-03-23 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: process the object log before asking for new memory
+ https://bugs.webkit.org/show_bug.cgi?id=155801
+
+ Reviewed by Gavin Barraclough.
+
+ This is a step toward merging large and small objects: In future, if we
+ have large objects in the log, we need to process them right away to
+ avoid pushing up peak memory use.
+
+ But it also appears to be a speedup and memory use improvement now.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::allocate):
+ (bmalloc::Allocator::refillAllocatorSlowCase):
+ (bmalloc::Allocator::allocateLarge): Process the log before asking for
+ more memory.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::processObjectLog):
+ (bmalloc::Deallocator::deallocateSlowCase):
+ * bmalloc/Deallocator.h: Provide a public API for processing the object log.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateSmallPage): Pop fragmented pages from the front
+ instead of from the back. This resolves a regression on tree_churn
+ --parallel. Popping from the front gives us the oldest pages. The oldest
+ pages have had the most time to accumulate free lines. They are therefore
+ the least fragmented on average.
+
+ * bmalloc/List.h:
+ (bmalloc::List::popFront):
+ (bmalloc::List::insertAfter): New API to pop from front.
+
+2016-03-22 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: use a log scale for large-ish size classes
+ https://bugs.webkit.org/show_bug.cgi?id=155770
+
+ Reviewed by Michael Saboff.
+
+ At larger sizes, precise allocation sizes don't save much memory -- and
+ they can cost memory when objects of distinct size classes can't
+ allocate together.
+
+ This is a small savings up to our current allocation limits, and it may
+ enable changing those limits in the long term.
+
+ * bmalloc/Algorithm.h:
+ (bmalloc::log2): We use this to compute large-ish size classes.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::Allocator): Iterate by size class instead of by
+ object size so we can change object size limits without breaking stuff.
+
+ (bmalloc::Allocator::scavenge): Ditto.
+
+ (bmalloc::Allocator::allocateLogSizeClass): New helper function for
+ allocating based on log size classes.
+
+ (bmalloc::Allocator::allocateSlowCase): Account for extra size class
+ possibilities.
+
+ * bmalloc/Allocator.h:
+ (bmalloc::Allocator::allocateFastCase): We only handle up to 512b on
+ the fastest fast path now.
+
+ * bmalloc/BumpAllocator.h:
+ (bmalloc::BumpAllocator::validate): Deleted. I noticed that this function
+ had been refactored not to do anything anymore.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::initializeLineMetadata): Iterate by size class. (See
+ Allocator::Allocator.)
+
+ * bmalloc/Heap.h: Use the sizeClassCount constant instead of hard coding
+ things.
+
+ * bmalloc/Sizes.h:
+ (bmalloc::Sizes::maskSizeClass):
+ (bmalloc::Sizes::maskObjectSize):
+ (bmalloc::Sizes::logSizeClass):
+ (bmalloc::Sizes::logObjectSize):
+ (bmalloc::Sizes::sizeClass):
+ (bmalloc::Sizes::objectSize): Separate size class calculation between
+ simple size classes that can be computed with a mask and are 8-byte-precise
+ and complex size classes that require more math and are less precise.
+
+ * bmalloc/SmallLine.h:
+ (bmalloc::SmallLine::ref):
+ * bmalloc/SmallPage.h:
+ (bmalloc::SmallPage::SmallPage):
+ (bmalloc::SmallPage::ref):
+ (bmalloc::SmallPage::deref): Cleaned up some ASSERTs that triggered
+ while working on this patch.
+
+ * bmalloc/Zone.cpp:
+ (bmalloc::statistics):
+ (bmalloc::zoneSize):
+ (bmalloc::Zone::Zone):
+ (bmalloc::size): Deleted. Renamed these symbols to work around an lldb
+ bug that makes it impossible to print out variables named 'size' -- which
+ can be a problem when working on malloc.
+
+2016-03-22 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: shrink largeMax
+ https://bugs.webkit.org/show_bug.cgi?id=155759
+
+ Reviewed by Michael Saboff.
+
+ If a largeChunk contains N bytes and we allocate objects of size
+ N / 2 + 8 bytes, then we waste 50% of physical memory at peak.
+
+ This patch sets largeMax to N / 2, reducing maximum waste to 25%.
+
+ * bmalloc/BoundaryTag.h:
+ * bmalloc/LargeChunk.h:
+ (bmalloc::LargeChunk::LargeChunk):
+ * bmalloc/SegregatedFreeList.cpp:
+ (bmalloc::SegregatedFreeList::SegregatedFreeList):
+ (bmalloc::SegregatedFreeList::insert): Honor largeMax vs largeObjectMax.
+
+ * bmalloc/Sizes.h: Distinguish between the largest thing we can store
+ in a free list (largeObjectMax) and the largest thing we're willing to
+ allocate (largeMax).
+
+2016-03-20 Dan Bernstein <mi...@apple.com>
+
+ [Mac] Determine TARGET_MAC_OS_X_VERSION_MAJOR from MACOSX_DEPLOYMENT_TARGET rather than from MAC_OS_X_VERSION_MAJOR
+ https://bugs.webkit.org/show_bug.cgi?id=155707
+ <rdar://problem/24980691>
+
+ Reviewed by Darin Adler.
+
+ * Configurations/Base.xcconfig: Set TARGET_MAC_OS_X_VERSION_MAJOR based on the last
+ component of MACOSX_DEPLOYMENT_TARGET.
+ * Configurations/DebugRelease.xcconfig: For engineering builds, preserve the behavior of
+ TARGET_MAC_OS_X_VERSION_MAJOR being the host’s OS version.
+
+2016-03-20 Dan Bernstein <mi...@apple.com>
+
+ Update build settings
+
+ Rubber-stamped by Andy Estes.
+
+ * Configurations/DebugRelease.xcconfig:
+
+2016-03-14 Geoffrey Garen <gg...@apple.com>
+
+ Unreviewed, rolling out r197955.
+
+ I decided to go in another direction
+
+ Reverted changeset:
+
+ "bmalloc: Rename SmallPage to SmallRun"
+ https://bugs.webkit.org/show_bug.cgi?id=155320
+ http://trac.webkit.org/changeset/197955
+
+2016-03-10 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Rename SmallPage to SmallRun
+ https://bugs.webkit.org/show_bug.cgi?id=155320
+
+ Reviewed by Alex Christensen.
+
+ A page is a fixed-size set of lines.
+
+ A run is an variable-sized set of lines.
+
+ We want to start using runs because:
+
+ (a) we want to support varying the hardware page size by OS;
+
+ (b) we want to support allocations larger than our current page size.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::reallocate):
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap):
+ (bmalloc::Heap::initializeSmallRunMetadata):
+ (bmalloc::Heap::scavenge):
+ (bmalloc::Heap::scavengeSmallRuns):
+ (bmalloc::Heap::allocateSmallBumpRanges):
+ (bmalloc::Heap::allocateSmallRun):
+ (bmalloc::Heap::deallocateSmallLine):
+ (bmalloc::Heap::initializeLineMetadata): Deleted.
+ (bmalloc::Heap::scavengeSmallPages): Deleted.
+ (bmalloc::Heap::allocateSmallPage): Deleted.
+ * bmalloc/Heap.h:
+ * bmalloc/LineMetadata.h:
+ * bmalloc/SmallChunk.h:
+ (bmalloc::SmallChunk::begin):
+ (bmalloc::SmallChunk::end):
+ (bmalloc::SmallChunk::lines):
+ (bmalloc::SmallChunk::runs):
+ (bmalloc::SmallChunk::SmallChunk):
+ (bmalloc::SmallLine::end):
+ (bmalloc::SmallRun::get):
+ (bmalloc::SmallRun::begin):
+ (bmalloc::SmallRun::end):
+ (bmalloc::SmallChunk::pages): Deleted.
+ (bmalloc::SmallPage::get): Deleted.
+ (bmalloc::SmallPage::begin): Deleted.
+ (bmalloc::SmallPage::end): Deleted.
+ * bmalloc/SmallPage.h: Removed.
+ * bmalloc/SmallRun.h: Copied from Source/bmalloc/bmalloc/SmallPage.h.
+ (bmalloc::SmallRun::SmallRun):
+ (bmalloc::SmallRun::ref):
+ (bmalloc::SmallRun::deref):
+ (bmalloc::SmallPage::SmallPage): Deleted.
+ (bmalloc::SmallPage::ref): Deleted.
+ (bmalloc::SmallPage::deref): Deleted.
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::allocateSmallChunk):
+ (bmalloc::VMHeap::allocateLargeChunk):
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateSmallRun):
+ (bmalloc::VMHeap::allocateLargeObject):
+ (bmalloc::VMHeap::deallocateSmallRun):
+ (bmalloc::VMHeap::deallocateLargeObject):
+ (bmalloc::VMHeap::allocateSmallPage): Deleted.
+ (bmalloc::VMHeap::deallocateSmallPage): Deleted.
+
+2016-03-08 Geoffrey Garen <gg...@apple.com>
+
+ Unreviewed, rolling in r197722.
+ https://bugs.webkit.org/show_bug.cgi?id=155171
+
+ The right calculation for our static_assert is actually:
+
+ sizeof(SmallChunk) % vmPageSize + 2 * smallMax <= vmPageSize
+
+ instead of:
+
+ sizeof(SmallChunk) % vmPageSize + smallMax <= vmPageSize
+
+ smallMax is not enough because line metadata might require us to begin
+ allocation at an offset as large as smallMax, so we need 2 * smallMax.
+
+ Once correct, this static_assert fires, and we fix it by increasing
+ the alignment of SmallChunk.
+
+ Restored changeset:
+
+ "bmalloc: Use List<T> instead of Vector<T> in some places"
+ https://bugs.webkit.org/show_bug.cgi?id=155150
+ http://trac.webkit.org/changeset/197722
+
+2016-03-08 Commit Queue <co...@webkit.org>
+
+ Unreviewed, rolling out r197722.
+ https://bugs.webkit.org/show_bug.cgi?id=155171
+
+ This change caused 800+ JSC test failures (Requested by
+ ryanhaddad on #webkit).
+
+ Reverted changeset:
+
+ "bmalloc: Use List<T> instead of Vector<T> in some places"
+ https://bugs.webkit.org/show_bug.cgi?id=155150
+ http://trac.webkit.org/changeset/197722
+
+2016-03-07 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Use List<T> instead of Vector<T> in some places
+ https://bugs.webkit.org/show_bug.cgi?id=155150
+
+ Reviewed by Andreas Kling.
+
+ Vector<T> is expensive when you want a lot of them because our minimum
+ allocation size is the system page size.
+
+ * bmalloc.xcodeproj/project.pbxproj: Added a List<T> class.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::scavengeSmallPages):
+ (bmalloc::Heap::allocateSmallPage): Use the List<T> API. No need to check
+ for stale entries anymore because List<T> supports O(1) eager removal
+ and we remove eagerly now.
+
+ (bmalloc::Heap::deallocateSmallLine): Remove eagerly. This simplifies
+ the allocation code and it is also required for correctness since we
+ only have enough metadata to be in one list at a time.
+
+ * bmalloc/Heap.h: List!
+
+ * bmalloc/SmallChunk.h: Made this assert a little more precise since this
+ patch triggered the old version in a benign way.
+
+ (bmalloc::SmallChunk::SmallChunk): This code moved to the SmallPage
+ constructor.
+
+ * bmalloc/SmallPage.h:
+ (bmalloc::SmallPage::SmallPage): Accomodate the List<T> data structure.
+ This is a net memory savings on Mac for heaps smaller than ~128MB and on
+ iOS for heaps smaller than ~512MB. The maximum memory saved is 512kB on
+ Mac and 2MB on iOS. For larger heaps, there's a memory cost of 0.4% on
+ Mac and 0.1% on iOS.
+
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateSmallPage): Use List<T> API.
+
+2016-03-03 Geoffrey Garen <gg...@apple.com>
+
+ Unreviewed, rolling in r197174.
+ https://bugs.webkit.org/show_bug.cgi?id=154762
+
+ The right calculation for alignment is actually:
+
+ vmAlignment - getpagesize() + vmSize
+
+ instead of:
+
+ vmAlignment - vmPageSize + vmSize
+
+ The vmPageSize might be larger than getpagesize().
+
+ Restored changeset:
+
+ "bmalloc: Added a fast XLarge allocator"
+ https://bugs.webkit.org/show_bug.cgi?id=154720
+ http://trac.webkit.org/changeset/197174
+
+2016-02-26 Commit Queue <co...@webkit.org>
+
+ Unreviewed, rolling out r197174.
+ https://bugs.webkit.org/show_bug.cgi?id=154762
+
+ This change caused LayoutTests to crash on iOS simulator
+ (Requested by ryanhaddad on #webkit).
+
+ Reverted changeset:
+
+ "bmalloc: Added a fast XLarge allocator"
+ https://bugs.webkit.org/show_bug.cgi?id=154720
+ http://trac.webkit.org/changeset/197174
+
+2016-02-25 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Added a fast XLarge allocator
+ https://bugs.webkit.org/show_bug.cgi?id=154720
+
+ Reviewed by Andreas Kling.
+
+ This is a big speedup for XLarge allocations because it avoids mmap
+ and page fault churn. It also enables future design changes to handle
+ a smaller size range on the fast path.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+
+ * bmalloc/Algorithm.h:
+ (bmalloc::roundUpToMultipleOf):
+ (bmalloc::roundDownToMultipleOf): Added a non-constant round down.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::tryAllocate): XLarge no longer requires the caller
+ to align things.
+
+ (bmalloc::Allocator::allocate): Tweaked the alignment calculation for
+ clarity. When alignment and largeAlignment are equal, no adjustment
+ is necessary since all allocations guarantee largeAlignment.
+
+ (bmalloc::Allocator::reallocate): Updated for interface change.
+
+ Note that the new interface fixes some concurrency bugs. The old code
+ kept an iterator into the XLarge allocator across lock drop and acquisition,
+ which is not cool.
+
+ (bmalloc::Allocator::allocateXLarge): XLarge no longer requires the caller
+ to align things.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::scavengeXLargeObjects): Added scavenging for XLarge.
+
+ (bmalloc::Heap::allocateXLarge):
+
+ (bmalloc::Heap::splitAndAllocate): Split XLarge objects to xLargeAlignment.
+
+ (bmalloc::Heap::tryAllocateXLarge):
+ (bmalloc::Heap::xLargeSize):
+ (bmalloc::Heap::shrinkXLarge):
+ (bmalloc::Heap::deallocateXLarge): Allocate from our map before going
+ to the OS.
+
+ (bmalloc::Heap::findXLarge): Deleted.
+
+ * bmalloc/Heap.h:
+
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::split):
+
+ * bmalloc/ObjectType.h:
+ (bmalloc::isXLarge): Give XLarge objects an explicit alignment for clarity.
+
+ * bmalloc/Range.h:
+ (bmalloc::Range::size):
+ (bmalloc::Range::operator!):
+ (bmalloc::Range::operator bool):
+ (bmalloc::Range::operator<):
+ (bmalloc::canMerge):
+ (bmalloc::merge): Some helpers that were useful in writing this patch.
+
+ * bmalloc/Sizes.h:
+
+ * bmalloc/SortedVector.h: Added.
+ (bmalloc::SortedVector::Bucket::Bucket):
+ (bmalloc::SortedVector::Bucket::operator<):
+ (bmalloc::SortedVector::iterator::iterator):
+ (bmalloc::SortedVector::iterator::operator++):
+ (bmalloc::SortedVector::iterator::operator!=):
+ (bmalloc::SortedVector::iterator::operator*):
+ (bmalloc::SortedVector::iterator::operator->):
+ (bmalloc::SortedVector::iterator::skipDeletedBuckets):
+ (bmalloc::SortedVector::begin):
+ (bmalloc::SortedVector::end):
+ (bmalloc::SortedVector<T>::insert):
+ (bmalloc::SortedVector<T>::find):
+ (bmalloc::SortedVector<T>::get):
+ (bmalloc::SortedVector<T>::take):
+ (bmalloc::SortedVector<T>::shrinkToFit): A simple abstraction for keeping
+ a sorted vector. Insertion is average amortized log(n) because we keep
+ deleted buckets that we can reuse.
+
+ This is better than a tree because we get better locality, less memory
+ use, and simpler code. Also, trees require a node memory allocator, and
+ implementing a memory allocator in a memory allocator is no fun.
+
+ Arguably we should use a hash table instead. But that's more code, and
+ sorted vector has other nice properties that we might want to take
+ adavantage of in the future.
+
+ * bmalloc/VMAllocate.h:
+ (bmalloc::tryVMAllocate): Fixed an inaccuracy in the alignment calculation
+ here. This code was sort of trying to enforce the alignment that the
+ XLarge allocator enforces -- but it's better to enforce that alignment
+ there.
+
+ The right calculation is:
+
+ vmAlignment - vmPageSize + vmSize
+
+ because the worst case is when you are aligned to 0 + vmPageSize, and
+ you must walk forward vmAlignment - vmPageSize to reach the next
+ vmAlignment.
+
+ (bmalloc::tryVMExtend): Deleted. No need to go back to the OS for VM
+ since we manage our own.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::allocateLargeChunk): Updated for clarity. When we
+ grow the large heap we know that grown region is where the next allocation
+ will take place, so we return it directly instead of pushing it to the
+ free list.
+
+ This fixes a subtle bug where an overly conservative aligned allocation
+ algorithm can fail to allocate at all when it grows the heap.
+
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateLargeObject): Ditto.
+ (bmalloc::VMHeap::allocateLargeObject): Ditto.
+
+ * bmalloc/VMState.h:
+ (bmalloc::merge): Added a helper.
+
+ * bmalloc/Vector.h:
+ (bmalloc::Vector::begin):
+ (bmalloc::Vector::end):
+ (bmalloc::Vector::size):
+ (bmalloc::Vector::capacity):
+ (bmalloc::Vector::last):
+ (bmalloc::Vector::pop):
+ (bmalloc::Vector<T>::push):
+ (bmalloc::Vector<T>::pop):
+ (bmalloc::Vector<T>::shrink): Use a proper iterator API to play nice
+ with std algorithms.
+
+ (bmalloc::Vector<T>::insert): New function required by SortedVector.
+
+ (bmalloc::Vector<T>::reallocateBuffer):
+ (bmalloc::Vector<T>::shrinkCapacity): Allow for shrinking back all the way
+ to 0 because that's what shrinkToFit wants.
+ (bmalloc::Vector<T>::growCapacity):
+ (bmalloc::Vector<T>::shrinkToFit):
+
+ * bmalloc/XLargeMap.cpp: Added. Helper data structure for managing XLarge
+ objects. We have enough granularity in our metadata to represent any
+ kind of address range.
+
+ We store free ranges in a flat vector because most programs have very
+ few individual free XLarge ranges. (They usually merge.)
+
+ We store allocated ranges in a sorted vector because programs might
+ allocate lots of XLarge ranges. For example, if the XLarge minimum is
+ 128kB, and you have a 1GB process, that's 8192 ranges. Linear scan would
+ examine 8192 items but binary search only 13.
+
+ Empirically, this is 1.5X faster than our current large allocator if you
+ modify MallocBench/big to allocate XLarge objects and not to initialize
+ objects and you allocate 128kB-256kB objects in a 1GB address space.
+
+ (bmalloc::XLargeMap::takeFree): Be careful about overflow in this function
+ because we support super huge pointers, alignments, and sizes.
+
+ (bmalloc::XLargeMap::addFree): Merge eagerly on free because the cost
+ of missing an XLarge opportunity is catastrophic. Also, I discovered
+ by experiment that any allocator that doesn't merge eagerly can create
+ lots of subtle opportunities for snowballing fragmentation, as
+ fragmentation in range A forces you to chop up range B, and so on.
+
+ We allocate "first fit" (allocating the lowest address) because someone
+ wrote a paper once that said that it's the best algorithm to combat
+ fragmentation (even though worst case fragmentation is unavoidable
+ regardless of algorithm).
+
+ (bmalloc::XLargeMap::addAllocated):
+ (bmalloc::XLargeMap::getAllocated):
+ (bmalloc::XLargeMap::takeAllocated):
+ (bmalloc::XLargeMap::shrinkToFit):
+ (bmalloc::XLargeMap::takePhysical):
+ (bmalloc::XLargeMap::addVirtual):
+ * bmalloc/XLargeMap.h: Added.
+ (bmalloc::XLargeMap::Allocation::operator<):
+
+ * bmalloc/XLargeRange.h: Added.
+ (bmalloc::XLargeRange::XLargeRange):
+ (bmalloc::XLargeRange::vmState):
+ (bmalloc::XLargeRange::setVMState):
+ (bmalloc::canMerge):
+ (bmalloc::merge):
+ (bmalloc::XLargeRange::split): Helper for tracking VMState in a range.
+
+2016-02-23 Dan Bernstein <mi...@apple.com>
+
+ [Xcode] Linker errors display mangled names, but no longer should
+ https://bugs.webkit.org/show_bug.cgi?id=154632
+
+ Reviewed by Sam Weinig.
+
+ * Configurations/Base.xcconfig: Stop setting LINKER_DISPLAYS_MANGLED_NAMES to YES.
+
+2016-02-22 Konstantin Tokarev <an...@yandex.ru>
+
+ Fixed compilation of bmalloc with GCC 4.8 after r196873.
+ https://bugs.webkit.org/show_bug.cgi?id=154534
+
+ Reviewed by Mark Lam.
+
+ See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55382.
+
+ * bmalloc/LargeChunk.h:
+ * bmalloc/SmallChunk.h:
+
+2016-02-21 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Don't use a whole page for metadata
+ https://bugs.webkit.org/show_bug.cgi?id=154510
+
+ Reviewed by Andreas Kling.
+
+ (1) Don't round up metadata to a page boundary. This saves 1.5% dirty
+ memory on iOS and 0.2% on Mac. It also enables a future patch to allocate
+ smaller chunks without wasting memory.
+
+ (2) Initialize metadata lazily. This saves dirty memory when the program
+ allocates primarily small or large objects (but not both), leaving some
+ metadata uninitialized.
+
+ * bmalloc.xcodeproj/project.pbxproj: Medium objects are gone now.
+
+ * bmalloc/BumpAllocator.h:
+ (bmalloc::BumpAllocator::refill): Added an ASSERT to help debug a bug
+ I cause while working on this patch.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateSmallBumpRanges): Ditto.
+
+ (bmalloc::Heap::splitAndAllocate):
+ (bmalloc::Heap::allocateLarge): Updated for interface change.
+
+ * bmalloc/LargeChunk.h: Changed the boundaryTagCount calculation to
+ a static_assert.
+
+ Don't round up to page boundary. (See above.)
+
+ (bmalloc::LargeChunk::LargeChunk): Moved code here from LargeChunk::init.
+ A constructor is a more natural / automatic way to do this initialization.
+
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::init): Deleted. Moved to LargeChunk.
+
+ * bmalloc/Sizes.h: Chagned largeChunkMetadataSize to a simpler constant
+ because metadata size no longer varies by page size.
+
+ * bmalloc/SmallChunk.h:
+ (bmalloc::SmallChunk::begin):
+ (bmalloc::SmallChunk::end):
+ (bmalloc::SmallChunk::lines):
+ (bmalloc::SmallChunk::pages): Use std::array to make begin/end
+ calculations easier.
+
+ (bmalloc::SmallChunk::SmallChunk): Treat our metadata like a series
+ of allocated objects. We used to avoid trampling our metadata by
+ starting object memory at the next page. Now we share the first page
+ between metadata and objects, and we account for metadata explicitly.
+
+ * bmalloc/SuperChunk.h:
+ (bmalloc::SuperChunk::SuperChunk):
+ (bmalloc::SuperChunk::smallChunk):
+ (bmalloc::SuperChunk::largeChunk):
+ (bmalloc::SuperChunk::create): Deleted. Don't eagerly run the SmallChunk
+ and LargeChunk constructors. We'll run them lazily as needed.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::VMHeap):
+ (bmalloc::VMHeap::allocateSmallChunk):
+ (bmalloc::VMHeap::allocateLargeChunk):
+ (bmalloc::VMHeap::allocateSuperChunk):
+ (bmalloc::VMHeap::grow): Deleted. Track small and large chunks explicitly
+ so we can initialize them lazily.
+
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateSmallPage):
+ (bmalloc::VMHeap::allocateLargeObject): Specify whether we're allocating
+ a small or large chunk since we don't allocate both at once anymore.
+
+2016-02-20 Mark Lam <ma...@apple.com>
+
+ Use of inlined asm statements causes problems for -std=c99 builds.
+ https://bugs.webkit.org/show_bug.cgi?id=154507
+
+ Reviewed by Dan Bernstein.
+
+ * bmalloc/BAssert.h:
+
+2016-02-19 Joonghun Park <jh...@samsung.com>
+
+ Unreviewed. Fix debug build error since r196847
+
+ Fix gcc build warning appeared as below
+ by removing BASSERT(refCount <= maxRefCount).
+ error: comparison is always true due to limited range of data type
+ [-Werror=type-limits]
+
+ * bmalloc/SmallLine.h:
+ (bmalloc::SmallLine::ref): Deleted.
+
+2016-02-19 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Chunk, Page, and Line don't need to be class templates
+ https://bugs.webkit.org/show_bug.cgi?id=154480
+
+ Reviewed by Gavin Barraclough.
+
+ We needed class templates to distinguish between small and medium,
+ but medium is gone now.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/Chunk.h: Removed.
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::initializeLineMetadata):
+ (bmalloc::Heap::allocateSmallBumpRanges):
+ * bmalloc/Heap.h:
+ * bmalloc/Line.h: Removed.
+ * bmalloc/Page.h: Removed.
+ * bmalloc/Sizes.h:
+ * bmalloc/SmallChunk.h: Replaced with Source/bmalloc/bmalloc/Chunk.h.
+ (bmalloc::SmallChunk::begin):
+ (bmalloc::SmallChunk::end):
+ (bmalloc::SmallChunk::lines):
+ (bmalloc::SmallChunk::pages):
+ (bmalloc::SmallChunk::get):
+ (bmalloc::SmallLine::get):
+ (bmalloc::SmallLine::begin):
+ (bmalloc::SmallLine::end):
+ (bmalloc::SmallPage::get):
+ (bmalloc::SmallPage::begin):
+ (bmalloc::SmallPage::end):
+ (bmalloc::Chunk::begin): Deleted.
+ (bmalloc::Chunk::end): Deleted.
+ (bmalloc::Chunk::lines): Deleted.
+ (bmalloc::Chunk::pages): Deleted.
+ * bmalloc/SmallLine.h: Replaced with Source/bmalloc/bmalloc/Line.h.
+ (bmalloc::SmallLine::ref):
+ (bmalloc::SmallLine::deref):
+ (bmalloc::Line<Traits>::begin): Deleted.
+ (bmalloc::Line<Traits>::end): Deleted.
+ (bmalloc::Line<Traits>::ref): Deleted.
+ (bmalloc::Line<Traits>::deref): Deleted.
+ * bmalloc/SmallPage.h: Replaced with Source/bmalloc/bmalloc/Page.h.
+ (bmalloc::SmallPage::hasFreeLines):
+ (bmalloc::SmallPage::setHasFreeLines):
+ (bmalloc::SmallPage::ref):
+ (bmalloc::SmallPage::deref):
+ (bmalloc::Page::hasFreeLines): Deleted.
+ (bmalloc::Page::setHasFreeLines): Deleted.
+ (bmalloc::Page<Traits>::ref): Deleted.
+ (bmalloc::Page<Traits>::deref): Deleted.
+ * bmalloc/SmallTraits.h: Removed.
+
+2016-02-18 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Remove the concept of medium objects
+ https://bugs.webkit.org/show_bug.cgi?id=154436
+
+ Reviewed by Sam Weinig.
+
+ There's no need to distinguish medium objects from small: Small object
+ metadata works naturally for both as long as we allow an object to
+ span more than two small lines. (We already allow an object to span
+ more than one small line.)
+
+ This change reduces memory use because it eliminates the 1kB line size,
+ so we don't have to hold down 1kB lines for individual 264+ byte objects.
+
+ 1kB lines were always a bit of a compromise. The main point of bump
+ allocation is to take advantage of cache lines. Cache lines are usually
+ 64 bytes, so line sizes above 256 bytes are a bit of a stretch.
+
+ This change speeds up small object benchmarks because it eliminates the
+ branch to detect medium objects in deallocation log processing.
+
+ This change reduces virtual memory use from worst cast 4X to worst case
+ 2X because the medium chunk is gone. iOS cares about virtual memory use
+ and terminates apps above ~1GB, so this change gives us more breathing room.
+
+ This change slows down medium benchmarks a bit because we end up doing
+ more work to recycle fragmented medium objects. Overall, the tradeoff
+ seems justified, since we have a net speedup and a memory use savings.
+
+ * bmalloc.xcodeproj/project.pbxproj: Removed all the medium files. We
+ can simplify even further in a follow-up patch, removing the base class
+ templates for Chunk, Page, and Line as well.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::Allocator):
+ (bmalloc::Allocator::allocate):
+ (bmalloc::Allocator::reallocate):
+ (bmalloc::Allocator::scavenge):
+ (bmalloc::Allocator::refillAllocatorSlowCase):
+ (bmalloc::Allocator::refillAllocator):
+ (bmalloc::Allocator::allocateSlowCase): Medium is gone. Small max is the
+ new medium max.
+
+ * bmalloc/Allocator.h:
+ (bmalloc::Allocator::allocateFastCase): Ditto.
+
+ * bmalloc/BumpAllocator.h:
+ (bmalloc::BumpAllocator::validate):
+ (bmalloc::BumpAllocator::allocate): No more medium.
+
+ * bmalloc/Chunk.h: No more medium.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::processObjectLog): No check for medium. This is
+ a speedup.
+
+ (bmalloc::Deallocator::deallocateSlowCase): No more medium.
+
+ * bmalloc/Deallocator.h:
+ (bmalloc::Deallocator::deallocateFastCase): Ditto.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::initializeLineMetadata): The algorithm here changed from
+ iterating each line to iterating each object. This helps us accomodate
+ objects that might span more than two lines -- i.e., all objects between
+ (512 bytes, 1024 bytes].
+
+ (bmalloc::Heap::scavenge):
+ (bmalloc::Heap::scavengeSmallPages):
+ (bmalloc::Heap::scavengeLargeObjects): Medium is gone.
+
+ (bmalloc::Heap::allocateSmallBumpRanges): Allow for lines that allocate
+ zero objects. This happens when an object spans more than two lines --
+ the middle lines allocate zero objects.
+
+ Also set the "has free lines" bit to false if we consume the last free
+ line. This needs to be a bit now because not all pages agree on their
+ maximum refcount anymore, so we need an explicit signal for the transition
+ from maximum to maximum - 1.
+
+ (bmalloc::Heap::allocateSmallPage): This code didn't change; I just removed
+ the medium code.
+
+ (bmalloc::Heap::deallocateSmallLine): Changed the algorithm to check
+ hasFreeLines. See allocateSmallBumpRanges.
+
+ (bmalloc::Heap::scavengeMediumPages): Deleted.
+ (bmalloc::Heap::allocateMediumBumpRanges): Deleted.
+ (bmalloc::Heap::allocateMediumPage): Deleted.
+ (bmalloc::Heap::deallocateMediumLine): Deleted.
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::derefMediumLine): Deleted.
+
+ * bmalloc/LargeChunk.h:
+ (bmalloc::LargeChunk::get):
+ (bmalloc::LargeChunk::endTag):
+ * bmalloc/Line.h: No more medium.
+
+ * bmalloc/MediumChunk.h: Removed.
+ * bmalloc/MediumLine.h: Removed.
+ * bmalloc/MediumPage.h: Removed.
+ * bmalloc/MediumTraits.h: Removed.
+
+ * bmalloc/ObjectType.cpp:
+ (bmalloc::objectType):
+ * bmalloc/ObjectType.h:
+ (bmalloc::isSmall):
+ (bmalloc::isXLarge):
+ (bmalloc::isSmallOrMedium): Deleted.
+ (bmalloc::isMedium): Deleted. No more medium.
+
+ * bmalloc/Page.h:
+ (bmalloc::Page::sizeClass):
+ (bmalloc::Page::setSizeClass):
+ (bmalloc::Page::hasFreeLines):
+ (bmalloc::Page::setHasFreeLines): Add the free lines bit. You get better
+ codegen if you make it the low bit, since ref / deref can then add / sub
+ 2. So do that.
+
+ * bmalloc/Sizes.h:
+ (bmalloc::Sizes::sizeClass): Expand the small size class to include the
+ medium size class.
+
+ * bmalloc/SuperChunk.h:
+ (bmalloc::SuperChunk::SuperChunk):
+ (bmalloc::SuperChunk::smallChunk):
+ (bmalloc::SuperChunk::largeChunk):
+ (bmalloc::SuperChunk::mediumChunk): Deleted. No more medium.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::grow):
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateSmallPage): Set the has free lines bit before
+ returning a Page to the Heap since this is the correct default state
+ when we first allocate a page.
+
+ (bmalloc::VMHeap::allocateMediumPage): Deleted.
+ (bmalloc::VMHeap::deallocateMediumPage): Deleted.
+
+2016-02-19 Michael Saboff <ms...@apple.com>
+
+ bmalloc: Unify VMHeap and Heap LargeObjects free lists to reduce fragmentation
+ https://bugs.webkit.org/show_bug.cgi?id=154192
+
+ Reviewed by Geoffrey Garen.
+
+ Change the operation of Heap and VMHeap LargeObject free lists.
+ Renamed Owner to VMState to track the state of each LargeObject.
+ Physical - The pages have been allocated.
+ Virtual - The pages have not been allocated.
+ Mixed - The object contains a mixture of Physical and Virtual pages.
+ VMState uses one bit each for Physical and Virtual to simplify merging states
+ when merging two adjacent blocks. This change enforces the rule that objects in
+ the Heap free list must have have the Physical bit set in their VMState while objects
+ in the VMHeap free list must have the Physical bit clear. Thie means that the Heap
+ can have LargeObjects in Physical or Mixed VMState, but the VMHeap's free list can
+ only contain Virtual LargeObjects.
+
+ In both Heap::allocateLarge(), we now allocate physical pages if the LargeObject we
+ pull from the free list has any Virtual pages before we possilby split the
+ object. When we merge objects, the result might be made up of Mixed page allocations.
+ When allocating a Mixed LargeObject, we need to allocate memory for them as well.
+ The scavenger deallocates both Physical and Mixed LargeObjects, placing them back into
+ the VMHeap's free list.
+
+ When we allocate or deallocate Mixed LargeObjects, there are pages that within these
+ objects that will be redundantly modified. It would require additional metadata to
+ eliminate this redundancy.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/BoundaryTag.h:
+ (bmalloc::BoundaryTag::vmState): New helper.
+ (bmalloc::BoundaryTag::setVMState): New helper.
+ (bmalloc::BoundaryTag::owner): Deleted.
+ (bmalloc::BoundaryTag::setOwner): Deleted.
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::splitAndAllocate): New helpers.
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::vmState): New helper.
+ (bmalloc::LargeObject::setVMState): New helper.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::splitAndAllocate): New helpers.
+ (bmalloc::Heap::allocateLarge):
+ (bmalloc::Heap::deallocatePhysicalPages): Refactored from VMHeap::deallocateLargeObjectMemory.
+
+ * bmalloc/FreeList.cpp:
+ (bmalloc::FreeList::takeGreedy):
+ (bmalloc::FreeList::take):
+ (bmalloc::FreeList::removeInvalidAndDuplicateEntries):
+ * bmalloc/FreeList.h:
+ (bmalloc::FreeList::FreeList):
+ (bmalloc::FreeList::push):
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap):
+ (bmalloc::Heap::scavengeLargeObjects):
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::isValidAndFree):
+ (bmalloc::LargeObject::validateSelf):
+ * bmalloc/SegregatedFreeList.cpp:
+ (bmalloc::SegregatedFreeList::SegregatedFreeList): Changed to initialize our required Physical state.
+ * bmalloc/SegregatedFreeList.h:
+ (bmalloc::SegregatedFreeList::SegregatedFreeList):
+ (bmalloc::SegregatedFreeList::insert):
+ (bmalloc::SegregatedFreeList::takeGreedy):
+ (bmalloc::SegregatedFreeList::take):
+ Replaced Owner parameters and checks with VMState::HasPhysical.
+
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::prevCanMerge): Removed owner from tests.
+ (bmalloc::LargeObject::nextCanMerge): Removed owner from tests.
+ (bmalloc::LargeObject::merge): Removed owner from tests. Updated to merge VMStates andset the
+ VMState after the merge.
+
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::owner): Deleted.
+ (bmalloc::LargeObject::setOwner): Deleted.
+
+ * bmalloc/Owner.h: Removed.
+
+ * bmalloc/VMAllocate.h:
+ (bmalloc::vmAllocatePhysicalPagesSloppy): Changed to round begin down to eliminate the left to right
+ allocation constraint.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::grow): Large space managed like small or medium as a vector of LargeChunks.
+ (bmalloc::VMHeap::VMHeap): Changed to initialize our required Physical state.
+
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateLargeObject): These no longer allocate memory.
+ (bmalloc::VMHeap::deallocateLargeObject): Removed setOwner. Now we set the VMState after any merges.
+
+ * bmalloc/VMState.h: Copied from Source/bmalloc/bmalloc/Owner.h.
+ (bmalloc::VMState::VMState):
+ (bmalloc::VMState::hasPhysical):
+ (bmalloc::VMState::hasVirtual):
+ (bmalloc::VMState::merge):
+ (bmalloc::VMState::operator ==):
+ (bmalloc::VMState::operator unsigned):
+ New class with various helpers.
+
+2016-02-12 Michael Saboff <ms...@apple.com>
+
+ BASSERTs added in r196421 are causing debug test failures
+ https://bugs.webkit.org/show_bug.cgi?id=154113
+
+ Reviewed by Geoffrey Garen.
+
+ In VMHeap::deallocateLargeObject(), we drop the lock to deallocate the physical pages.
+ If the scavenger thread is running at the same time a synchronous call to scavenge()
+ comes in, we could call VMHeap::deallocateLargeObject() for an adjacent object while the
+ lock in the other thread is dropped. We fix this by checking for adjacent objects we
+ can merge with and loop if we have one.
+
+ * bmalloc/FreeList.h:
+ (bmalloc::FreeList::push): Added BASSERT to catch adding unmerged free objects
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateLarge): Changed to use nextCanMerge().
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::prevCanMerge): Repurposed prevIsAllocated.
+ (bmalloc::LargeObject::nextCanMerge): Repurposed nextIsAllocated.
+ (bmalloc::LargeObject::prevIsAllocated): Deleted.
+ (bmalloc::LargeObject::nextIsAllocated): Deleted.
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateLargeObject): Moved adding the extra object back to the free list
+ to after we set the object we'll return as being allocated.
+ (bmalloc::VMHeap::deallocateLargeObject):
+
+2016-02-12 Mark Lam <ma...@apple.com>
+
+ Make BCRASH() use breakpoint traps too for non-debug OS(DARWIN).
+ https://bugs.webkit.org/show_bug.cgi?id=154184
+
+ Reviewed by Saam Barati.
+
+ This makes it behave consistently with WTFCrash().
+
+ * bmalloc/BAssert.h:
+ * bmalloc/BPlatform.h:
+
+2016-02-11 Michael Saboff <ms...@apple.com>
+
+ Unreviewed build fix after r196421.
+
+ Removed BASSERTs that are firing to eliminate Debug build crashes. I'll debug locally and
+ enable or alter after the issue is understood.
+
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::merge): Removed BASSERTs that are firing.
+
+2016-02-11 Michael Saboff <ms...@apple.com>
+
+ bmalloc: large aligned allocations will put 1 or 2 free object on free list without merging with free neighbors
+ https://bugs.webkit.org/show_bug.cgi?id=154091
+
+ Reviewed by Geoffrey Garen.
+
+ If we split off any unused free object in the aligned version of Heap::allocateLarge(), we merge them with
+ free neighbors before putting them back on the free list. Added helpers to verify that when we
+ add LargeObjects to the free list their neighbors are allocated.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateLarge): Deleted private helper version and rolled it into the two the
+ two public versions of allocateLarge().
+ * bmalloc/Heap.h:
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::prevIsAllocated): New helper.
+ (bmalloc::LargeObject::nextIsAllocated): New helper.
+ (bmalloc::LargeObject::merge): Check that the merge object has allocated neighbors.
+
+2016-02-05 Saam barati <sb...@apple.com>
+
+ bmalloc: largeMax calculation is wrong on iOS
+ https://bugs.webkit.org/show_bug.cgi?id=153923
+
+ Reviewed by Mark Lam.
+
+ Our number for largeMax was larger than what we had
+ space to actually allocate inside the LargeChunk. This made
+ it so that we would allocate a large object for something
+ that really should be extra large. Previously:
+ largeMax + sizeof(LargeChunk) > 1MB
+ which meant that when we would grow() to accommodate an allocation
+ of a particular size inside a LargeObject despite the fact that
+ the allocation size would be too large to actually fit in the LargeObject.
+ This would manifest when we had an allocation size in the range:
+ 1MB - sizeof(LargeChunk) < allocation size < largeMax
+
+ We fix this bug by being precise in our calculation of largeMax
+ instead of just assuming largeChunkSize * 99/100 is enough
+ space for the metadata.
+
+ * bmalloc/LargeChunk.h:
+ (bmalloc::LargeChunk::get):
+ * bmalloc/Sizes.h:
+
+2016-01-31 Dan Bernstein <mi...@apple.com>
+
+ [Cocoa] Remove unused definition of HAVE_HEADER_DETECTION_H
+ https://bugs.webkit.org/show_bug.cgi?id=153729
+
+ Reviewed by Sam Weinig.
+
+ After r141700, HAVE_HEADER_DETECTION_H is no longer used.
+
+ * Configurations/Base.xcconfig:
+
+2015-12-19 Dan Bernstein <mi...@apple.com>
+
+ [Mac] WebKit contains dead source code for OS X Mavericks and earlier
+ https://bugs.webkit.org/show_bug.cgi?id=152462
+
+ Reviewed by Alexey Proskuryakov.
+
+ * Configurations/DebugRelease.xcconfig: Removed definition of MACOSX_DEPLOYMENT_TARGET for
+ OS X 10.9.
+
+2015-12-03 Anders Carlsson <an...@apple.com>
+
+ Remove Objective-C GC support
+ https://bugs.webkit.org/show_bug.cgi?id=151819
+ rdar://problem/23746991
+
+ Reviewed by Dan Bernstein.
+
+ * Configurations/Base.xcconfig:
+
+2015-12-03 Michael Saboff <ms...@apple.com>
+
+ bmalloc: extra large allocations could be more efficient
+ https://bugs.webkit.org/show_bug.cgi?id=151817
+
+ Reviewed by Geoffrey Garen.
+
+ Reduced the super chunk size from 4MB to 2MB.
+
+ Added path to reallocate() of an extra large object to see if we can extend the allocation.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::reallocate):
+ * bmalloc/SegregatedFreeList.h:
+ * bmalloc/Sizes.h:
+ * bmalloc/VMAllocate.h:
+ (bmalloc::tryVMAllocate):
+ (bmalloc::tryVMExtend):
+ (bmalloc::vmAllocate):
+
+2015-11-11 Akos Kiss <ak...@inf.u-szeged.hu>
+
+ bmalloc: Add libdl dependency
+ https://bugs.webkit.org/show_bug.cgi?id=151140
+
+ Reviewed by Csaba Osztrogonác.
+
+ Make sure that the linker links libdl and finds the references to
+ dlopen, dlsym and dlclose in Environment.cpp.
+
+ * CMakeLists.txt:
+
+2015-11-02 Andy Estes <ae...@apple.com>
+
+ [Cocoa] Add tvOS and watchOS to SUPPORTED_PLATFORMS
+ https://bugs.webkit.org/show_bug.cgi?id=150819
+
+ Reviewed by Dan Bernstein.
+
+ This tells Xcode to include these platforms in its Devices dropdown, making it possible to build in the IDE.
+
+ * Configurations/Base.xcconfig:
+
+2015-11-01 Philip Chimento <ph...@gmail.com>
+
+ [GTK] Fix combinations of PLATFORM(GTK) and OS(DARWIN)
+ https://bugs.webkit.org/show_bug.cgi?id=144560
+
+ Reviewed by Darin Adler.
+
+ * PlatformGTK.cmake: Added. This adds Zone.cpp to the PlatformGTK
+ build, on Darwin only. Since there was previously nothing for the
+ build system to do that was specific to the GTK platform in
+ bmalloc, we need to create this file.
+
+2015-10-29 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: AsyncTask should handle destruction
+ https://bugs.webkit.org/show_bug.cgi?id=150648
+
+ Reviewed by Mark Lam.
+
+ So we can use it in more places.
+
+ * bmalloc/AsyncTask.h: Use std::thread instead of pthread because it
+ should be more portable.
+
+ (bmalloc::Function>::AsyncTask): Renamed Signaled to RunRequested for
+ clarity. Added an ExitRequested state.
+
+ (bmalloc::Function>::~AsyncTask): Wait for our child thread to exit
+ before destroying ourselves because our child thread will modify our
+ data (and might modify our client's data). Note that we only need to
+ wait for the last child thread since any prior child thread, having
+ reached the Exited condition, is guaranteed not to read or write any
+ data.
+
+ (bmalloc::Function>::run):
+ (bmalloc::Function>::runSlowCase): Updated for interface changes. Also
+ changed to use our WebKit style for condition signal: Hold the lock
+ during the signal and always notify all. Technically, neither is necessary,
+ but it is easier to understand the code this way, and harder to make
+ mistakes.
+
+ (bmalloc::Function>::threadEntryPoint):
+ (bmalloc::Function>::threadRunLoop): Handle the new ExitRequested state.
+ Technically, this state has no meaningful difference from the Exited
+ state, but it is nice to be explicit.
+
+ (bmalloc::Function>::join): Deleted.
+ (bmalloc::Function>::pthreadEntryPoint): Deleted.
+ (bmalloc::Function>::entryPoint): Deleted.
+
+2015-10-15 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: per-thread cache data structure should be smaller
+ https://bugs.webkit.org/show_bug.cgi?id=150218
+
+ Reviewed by Andreas Kling.
+
+ Reduce the number of entries in the range cache because it's really
+ big, and the bigness only helps in cases of serious fragmentation, and
+ it only saves us a little bit of lock acquisition time.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::scavenge):
+ (bmalloc::Allocator::refillAllocatorSlowCase):
+ (bmalloc::Allocator::refillAllocator):
+ (bmalloc::Allocator::allocateLarge):
+ (bmalloc::Allocator::allocateSlowCase):
+ (bmalloc::Allocator::allocateBumpRangeSlowCase): Deleted.
+ (bmalloc::Allocator::allocateBumpRange): Deleted.
+ * bmalloc/Allocator.h: Pass through the empty allocator and the range
+ cache when refilling, and refill both. Otherwise, we always immediately
+ pop the last item in the range cache, wasting that slot of capacity.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateSmallBumpRanges):
+ (bmalloc::Heap::allocateMediumBumpRanges): Account for the fact that
+ the range cache is no longer big enough to guarantee that it can hold
+ all the ranges in a page.
+
+ (bmalloc::Heap::refillSmallBumpRangeCache): Deleted.
+ (bmalloc::Heap::refillMediumBumpRangeCache): Deleted.
+
+ * bmalloc/Heap.h: Move VMHeap to the end of the object because it
+ contains a lot of unused / wasted space, and we want to pack our data
+ together in memory.
+
+ * bmalloc/Sizes.h: Make the range cache smaller.
+
+2015-10-13 Chris Dumez <cd...@apple.com>
+
+ Avoid useless copies in range-loops that are using 'auto'
+ https://bugs.webkit.org/show_bug.cgi?id=150091
+
+ Reviewed by Sam Weinig.
+
+ Avoid useless copies in range-loops that are using 'auto'. Also use
+ 'auto*' instead of 'auto' when range values are pointers for clarity.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::processObjectLog):
+
+2015-10-12 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Don't ASSERT that all syscalls succeed
+ https://bugs.webkit.org/show_bug.cgi?id=150047
+ <rdar://problem/22649531>
+
+ Reviewed by Mark Lam.
+
+ madvise can fail due to VM behaviors outside of our control:
+ copy-on-write, fork, mprotect, and other stuff.
+
+ Older darwin kernels sometimes return this error value, and new kernels
+ might again in future.
+
+ We haven't gained much from this ASSERT so far, so let's remove it.
+
+ Perhaps in future we can come up with a scheme that makes madvise
+ never fail, or that responds to failure.
+
+ * bmalloc/Syscall.h:
+
+2015-10-10 Dan Bernstein <mi...@apple.com>
+
+ [iOS] Remove project support for iOS 8
+ https://bugs.webkit.org/show_bug.cgi?id=149993
+
+ Reviewed by Alexey Proskuryakov.
+
+ * Configurations/Base.xcconfig:
+ * Configurations/bmalloc.xcconfig:
+ * Configurations/mbmalloc.xcconfig:
+
+2015-08-31 Michael Catanzaro <mc...@igalia.com>
+
+ Implement bmalloc::isASanEnabled for generic Unix
+ https://bugs.webkit.org/show_bug.cgi?id=148623
+
+ Reviewed by Geoffrey Garen.
+
+ * bmalloc/BPlatform.h: Add BOS_UNIX to detect whether the OS is a Unix.
+ * bmalloc/Environment.cpp:
+ (bmalloc::isASanEnabled): Implement a runtime check that should work on any Unix.
+
+2015-08-19 Geoffrey Garen <gg...@apple.com>
+
+ Crash @ bmalloc::Environment::computeIsBmallocEnabled
+ https://bugs.webkit.org/show_bug.cgi?id=148183
+
+ Reviewed by NOBODY Michael Saboff.
+
+ CrashTracer says we have some crashes beneath computeIsBmallocEnabled
+ dereferencing null in strstr. We null check getenv but not
+ _dyld_get_image_name, so deduction indicates that _dyld_get_image_name
+ must be returning null. _dyld_get_image_name isn't really documented,
+ so let's assume it can return null.
+
+ * bmalloc/Environment.cpp:
+ (bmalloc::isASanEnabled): Check _dyld_get_image_name's return value for
+ null because we can't prove it won't be null.
+
+2015-07-24 Geoffrey Garen <gg...@apple.com>
+
+ vmmap crash at JavaScriptCore: 0x31cd12f6 (the JavaScript malloc zone enumerator)
+ https://bugs.webkit.org/show_bug.cgi?id=147274
+
+ Reviewed by Anders Carlsson.
+
+ It's not really clear why vmmap sometimes fails to read the target
+ process, but we can avoid a crash when it does. This is useful because
+ you'll still get all the non-bmalloc data out of the target process,
+ and bmalloc might not even be relevant to your investigation.
+
+ * bmalloc/Zone.cpp:
+ (bmalloc::remoteRead): Check for failure.
+
+2015-07-24 Geoffrey Garen <gg...@apple.com>
+
+ JavaScriptCore bmalloc should not register its malloc zone more than once
+ https://bugs.webkit.org/show_bug.cgi?id=147273
+
+ Reviewed by Andreas Kling.
+
+ This was a goof: The Zone constructor, by virtue of running automatically,
+ was registering a Zone inside the analysis process.
+
+ * bmalloc/Zone.cpp:
+ (bmalloc::remoteRead): Clarify that the pointer is remote.
+
+ (bmalloc::enumerator):
+ (bmalloc::Zone::Zone):
+ * bmalloc/Zone.h: Separate the normal constructor and the remote constructor.
+ The remote constructor skips zone registration since its goal is not
+ to register a zone in the current process or do any allocation but rather
+ to mirror the bytes of the zone from the target process.
+
+2015-07-23 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Shrink the super chunk size (again)
+ https://bugs.webkit.org/show_bug.cgi?id=147240
+
+ Reviewed by Andreas Kling.
+
+ Shrinking to 8MB reduced VM exhaustion crashes but did not eliminate them.
+ Let's try 4MB.
+
+ (My previous comment was that the maximum fast object was 2MB. But it
+ was 4MB! Now it's 2MB for realsies.)
+
+ * bmalloc/Sizes.h:
+
+2015-07-03 Dan Bernstein <mi...@apple.com>
+
+ [Xcode] Update some build settings as recommended by Xcode 7
+ https://bugs.webkit.org/show_bug.cgi?id=146597
+
+ Reviewed by Sam Weinig.
+
+ * Configurations/Base.xcconfig: Enabled CLANG_WARN_UNREACHABLE_CODE, GCC_NO_COMMON_BLOCKS,
+ and ENABLE_STRICT_OBJC_MSGSEND. Removed GCC_MODEL_TUNING.
+
+ * bmalloc.xcodeproj/project.pbxproj: Updated LastUpgradeCheck.
+
+2015-07-02 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Shrink the super chunk size
+ https://bugs.webkit.org/show_bug.cgi?id=146519
+
+ Reviewed by Andreas Kling.
+
+ We have lots of reports of crashing due to failed VM allocation on iOS.
+ (This VM limit on iOS is usually 1GB-2GB, and has been as low as 256MB.)
+
+ Shrink the super chunk size in case fragmentation is the reason for
+ VM allocation failure.
+
+ This has the downside that >= 2MB allocations will now be super slow,
+ but they are also super rare (as in never on most websites), so this
+ is probably an OK tradeoff.
+
+ * bmalloc/Sizes.h:
+
+2015-07-01 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: realloc of an XLarge range can unmap adjacent VM ranges
+ https://bugs.webkit.org/show_bug.cgi?id=146535
+
+ Reviewed by Anders Carlsson.
+
+ This bug causes a crash when running fast/css/large-list-of-rules-crash.html
+ with the fix applied for https://bugs.webkit.org/show_bug.cgi?id=146519.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::reallocate): Start at object + newSize since starting
+ at object + oldSize means deleting the adjacent VM range.
+
+2015-05-26 Geoffrey Garen <gg...@apple.com>
+
+ Integer overflow in XLarge allocation (due to unchecked roundUpToMultipleOf)
+ https://bugs.webkit.org/show_bug.cgi?id=145385
+
+ Reviewed by Andreas Kling.
+
+ Added some checking to verify that round-up operations will not overflow
+ a size_t.
+
+ The simplest way to do this was to introduce a notion of xLargeMax, like
+ we have for smallMax, mediumMax, and largeMax. It's a bit surprising at
+ first to think that there is an xLargeMax, since xLarge is what we use
+ to handle the biggest things. But computers have limits, so it makes sense.
+
+ FWIW, TCMalloc used to have an xLargeMax too, which it called kMaxValidPages.
+
+ No test because this bug was found by code inspection and I don't know
+ of a practical way to convince WebKit to make an allocation this large.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::tryAllocate):
+ (bmalloc::Allocator::allocate):
+ (bmalloc::Allocator::reallocate):
+ (bmalloc::Allocator::allocateSlowCase): Check against xLargeMax to avoid
+ overflow when rounding up.
+
+ * bmalloc/BAssert.h: Added support for explicit crashing.
+
+ * bmalloc/Sizes.h:
+
+2015-05-26 Dan Bernstein <mi...@apple.com>
+
+ <rdar://problem/21104551> Update build settings
+
+ Reviewed by Anders Carlsson.
+
+ * Configurations/DebugRelease.xcconfig:
+
+2015-05-23 Dan Bernstein <mi...@apple.com>
+
+ Remove unused definitions of WEBKIT_VERSION_MIN_REQUIRED
+ https://bugs.webkit.org/show_bug.cgi?id=145345
+
+ Reviewed by Sam Weinig.
+
+ * Configurations/Base.xcconfig: Also changed to use $(inherited).
+
+2015-05-07 Geoffrey Garen <gg...@apple.com>
+
+ Release assert in com.apple.WebKit.WebContent under JavaScriptCore: JSC::JSONProtoFuncStringify
+ https://bugs.webkit.org/show_bug.cgi?id=144758
+
+ Reviewed by Andreas Kling.
+
+ This was an out-of-memory error when trying to shrink a string builder.
+ bmalloc was missing the optimization that allowed realloc() to shrink
+ without copying. So, let's add it.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::reallocate): Added Large and XLarge cases for
+ shrinking without copying. This isn't possible for small and medium
+ objects, and probably not very profitable, either.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::findXLarge):
+ (bmalloc::Heap::deallocateXLarge):
+ * bmalloc/Heap.h: Refactored this code to return a reference to an
+ XLarge range. This makes the code reusable, and also makes it easier
+ for realloc() to update metadata.
+
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::split): Allow allocated objects to split because
+ that's what realloc() wants to do, and there's nothing intrinsically
+ wrong with it.
+
+2015-05-07 Dan Bernstein <mi...@apple.com>
+
+ <rdar://problem/19317140> [Xcode] Remove usage of AspenFamily.xcconfig in Source/
+ https://bugs.webkit.org/show_bug.cgi?id=144727
+
+ Reviewed by Darin Adler.
+
+ * Configurations/Base.xcconfig: Dont’s include AspenFamily.xcconfig, and define
+ INSTALL_PATH_PREFIX for the iOS 8.x Simulator.
+
+2015-04-01 Alex Christensen <ac...@webkit.org>
+
+ Progress towards CMake on Windows and Mac.
+ https://bugs.webkit.org/show_bug.cgi?id=143293
+
+ Reviewed by Filip Pizlo.
+
+ * bmalloc/BAssert.h:
+ Removed ellipses from macros to appease Visual Studio.
+
+2015-03-13 Alex Christensen <ac...@webkit.org>
+
+ Progress towards CMake on Mac.
+ https://bugs.webkit.org/show_bug.cgi?id=142680
+
+ Reviewed by Gyuyoung Kim.
+
+ * CMakeLists.txt:
+ * PlatformMac.cmake:
+ Added Zone.cpp to Mac CMake builds.
+
+2015-03-12 Geoffrey Garen <gg...@apple.com>
+
+ Assertion failure in bmalloc::LargeObject::validateSelf on Mavericks Debug layout test bot
+ https://bugs.webkit.org/show_bug.cgi?id=142642
+
+ Reviewed by Michael Saboff.
+
+ The typical backtrace to this crash shows the main thread trying to
+ realloc a large string while a DFG compiler thread tries to
+ free a large vector buffer.
+
+ I believe that this is a race condition -- at least in debug builds --
+ since the main thread will try to validate its object's neighbors
+ without holding a lock, even though those neighbors might be in the
+ midst of changing.
+
+ In general, there may be sneaky times when it is valid to look at an
+ object's metadata without holding the heap lock, but it is best not to
+ do so unless we have a really really good reason to.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::reallocate): Take a lock before reading the metadata
+ for this object, since we generally require any access to shared heap
+ metadata to take a lock.
+
+2015-03-10 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: tryFastMalloc shouldn't crash
+ https://bugs.webkit.org/show_bug.cgi?id=142443
+
+ Reviewed by Sam Weinig.
+
+ Rolling back in r181307 with a check for whether bmalloc is enabled, to
+ avoid crashes when running with ASan and GuardMalloc.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::tryAllocate):
+ * bmalloc/Allocator.h:
+ * bmalloc/Cache.cpp:
+ (bmalloc::Cache::tryAllocateSlowCaseNullCache):
+ * bmalloc/Cache.h:
+ (bmalloc::Cache::tryAllocate):
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateXLarge):
+ (bmalloc::Heap::tryAllocateXLarge):
+ * bmalloc/Heap.h:
+ * bmalloc/VMAllocate.h:
+ (bmalloc::tryVMAllocate):
+ (bmalloc::vmAllocate):
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::tryMalloc):
+ (bmalloc::api::realloc):
+ (bmalloc::api::free):
+
+2015-03-09 Commit Queue <co...@webkit.org>
+
+ Unreviewed, rolling out r181307.
+ https://bugs.webkit.org/show_bug.cgi?id=142525
+
+ Broke ASan tests (Requested by ap on #webkit).
+
+ Reverted changeset:
+
+ "bmalloc: tryFastMalloc shouldn't crash"
+ https://bugs.webkit.org/show_bug.cgi?id=142443
+ http://trac.webkit.org/changeset/181307
+
+2015-03-09 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: tryFastMalloc shouldn't crash
+ https://bugs.webkit.org/show_bug.cgi?id=142443
+
+ Reviewed by Darin Adler.
+
+ Added support for tryMalloc.
+
+ We assume that non-x-large allocations always succeed, and we crash
+ otherwise, since normal allocation failure will just cause the next
+ non-try allocation or internal metadata allocation to fail, and it's
+ hard and not really useful to keep limping along after that. But
+ extra-large allocations can meaningfully fail, and we can recover.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateXLarge):
+ (bmalloc::Heap::tryAllocateXLarge):
+ * bmalloc/Heap.h: Added support for non-crashy x-large allocation.
+
+ * bmalloc/VMAllocate.h:
+ (bmalloc::tryVMAllocate):
+ (bmalloc::vmAllocate): Added support for non-crashy VM allocation.
+
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::tryMalloc):
+ (bmalloc::api::realloc):
+ (bmalloc::api::free): Tried to clarify our behavior with some comments.
+ Unfortunately, calling what we do "malloc" is still not quite right, since
+ malloc returns null on failure and we don't.
+
+2015-03-03 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Don't branch when setting the owner of a large object
+ https://bugs.webkit.org/show_bug.cgi?id=142241
+
+ Reviewed by Andreas Kling.
+
+ * bmalloc/BoundaryTag.h:
+ (bmalloc::BoundaryTag::owner):
+ (bmalloc::BoundaryTag::setOwner):
+
+2015-03-03 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc should implement malloc introspection (to stop false-positive leaks when MallocStackLogging is off)
+ https://bugs.webkit.org/show_bug.cgi?id=141802
+
+ Reviewed by Andreas Kling.
+
+ Re-enabled this feature on iOS, now that the iOS crash should be fixed.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::grow):
+ * bmalloc/VMHeap.h:
+
+2015-03-03 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Added missing features to the malloc zone introspection API
+ https://bugs.webkit.org/show_bug.cgi?id=142235
+
+ Reviewed by Andreas Kling.
+
+ This should fix the crash we saw on the iOS PLT bot
+ (c.f. http://trac.webkit.org/changeset/180604).
+
+ * bmalloc/Zone.cpp:
+ (bmalloc::good_size):
+ (bmalloc::check):
+ (bmalloc::print):
+ (bmalloc::log):
+ (bmalloc::force_lock):
+ (bmalloc::force_unlock):
+ (bmalloc::statistics):
+ (bmalloc::size):
+ (bmalloc::enumerator): Provide all of these functions since they are called
+ indiscriminately on all zones.
+
+ (bmalloc::Zone::Zone):
+ (bmalloc::Zone::size): Deleted.
+ (bmalloc::Zone::enumerator): Deleted. Moved these functions out of the
+ Zone class since they can stand alone.
+
+ * bmalloc/Zone.h:
+
+2015-03-03 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc should implement malloc introspection (to stop false-positive leaks when MallocStackLogging is off)
+ https://bugs.webkit.org/show_bug.cgi?id=141802
+
+ Reviewed by Andreas Kling.
+
+ Rolling back in but disabled on iOS until I can debug why the iOS PLT crashes.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::grow):
+ * bmalloc/VMHeap.h:
+ * bmalloc/Zone.cpp:
+ (bmalloc::Zone::size):
+ (bmalloc::Zone::Zone):
+ * bmalloc/Zone.h:
+
+2015-03-03 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Miscellaneous cleanup
+ https://bugs.webkit.org/show_bug.cgi?id=142231
+
+ Reviewed by Andreas Kling.
+
+ No performance change -- maybe a tiny reduction in memory use.
+
+ * bmalloc/Heap.cpp: Moved the sleep function into StaticMutex, since
+ it's a helper for working with mutexes.
+
+ (bmalloc::Heap::scavenge): Make sure to wait before we start any
+ scavenging, since individual scavenging functions now always scavenge
+ at least one page before waiting themselves.
+
+ (bmalloc::Heap::scavengeSmallPages):
+ (bmalloc::Heap::scavengeMediumPages):
+ (bmalloc::Heap::scavengeLargeObjects): Use the new wait helper to
+ simplify this code. Also, we now require our caller to wait until at
+ least one deallocation is desirable. This simplifies our loop.
+
+ (bmalloc::Heap::allocateSmallPage):
+ (bmalloc::Heap::allocateMediumPage):
+ (bmalloc::Heap::allocateXLarge):
+ (bmalloc::Heap::allocateLarge): Don't freak out any time the heap does
+ an allocation. Only consider the heap to be growing if it actually needs
+ to allocate new VM. This allows us to shrink the heap back down from a
+ high water mark more reliably even if heap activity continues.
+
+ (bmalloc::sleep): Deleted.
+ (bmalloc::Heap::scavengeLargeRanges): Renamed to match our use of
+ "LargeObject".
+
+ * bmalloc/Heap.h:
+
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::operator bool): Added to simplify a while loop.
+
+ * bmalloc/StaticMutex.h:
+ (bmalloc::sleep):
+ (bmalloc::waitUntilFalse): New helper for waiting until a condition
+ becomes reliably false.
+
+ * bmalloc/Vector.h:
+ (bmalloc::Vector<T>::~Vector): Oops! Don't deallocate the null pointer.
+ We don't actually run any Vector destructors, but an iteration of this
+ patch did, and then crashed. So, let's fix that.
+
+2015-03-02 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Eagerly remove allocated objects from the free list
+ https://bugs.webkit.org/show_bug.cgi?id=142194
+
+ Reviewed by Andreas Kling.
+
+ This reduces the pressure to garbage collect the free list.
+
+ Might be a 1% speedup on MallocBench.
+
+ * bmalloc/FreeList.cpp: Put this comment at the top of the file instead
+ of repeating it inside of each function. Tried to clarify the details.
+
+ (bmalloc::FreeList::takeGreedy): Matched the other iteration code in this
+ file for consistency -- even though either direction works fine in this
+ function.
+
+ (bmalloc::FreeList::take): Change to iterate from low to high so that we
+ can maintain an index into the vector that is not disturbed even if we
+ pop from the middle (which invalidates the last index in the vector).
+
+ Decrement i when popping from the middle to make sure that we don't
+ skip the next item after popping.
+
+ (bmalloc::FreeList::removeInvalidAndDuplicateEntries): Ditto.
+
+2015-02-27 Ryosuke Niwa <rn...@webkit.org>
+
+ Fixed a typo in the previous commit.
+
+ * bmalloc/BoundaryTag.h:
+ (bmalloc::BoundaryTag::setOwner):
+
+2015-02-27 Ryosuke Niwa <rn...@webkit.org>
+
+ EFL build fix after r180797.
+
+ * bmalloc/BoundaryTag.h:
+ (bmalloc::BoundaryTag::owner):
+ (bmalloc::BoundaryTag::setOwner):
+
+2015-02-27 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Pathological madvise churn on the free(malloc(x)) benchmark
+ https://bugs.webkit.org/show_bug.cgi?id=142058
+
+ Reviewed by Andreas Kling.
+
+ The churn was caused by repeatedly splitting an object with physical
+ pages from an object without, and then merging them back together again.
+ The merge would conservatively forget that we had physical pages, forcing
+ a new call to madvise on the next allocation.
+
+ This patch more strictly segregates objects in the heap from objects in
+ the VM heap, with these changes:
+
+ (1) Objects in the heap are not allowed to merge with objects in the VM
+ heap, and vice versa -- since that would erase our precise knowledge of
+ which physical pages had been allocated.
+
+ (2) The VM heap is exclusively responsible for allocating and deallocating
+ physical pages.
+
+ (3) The heap free list must consider entries for objects that are in the
+ VM heap to be invalid, and vice versa. (This condition can arise
+ because the free list does not eagerly remove items.)
+
+ With these changes, we can know that any valid object in the heap's free
+ list already has physical pages, and does not need to call madvise.
+
+ Note that the VM heap -- as before -- might sometimes contain ranges
+ or pieces of ranges that have physical pages, since we allow splitting
+ of ranges at granularities smaller than the VM page size. These ranges
+ can eventually merge with ranges in the heap during scavenging.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+
+ * bmalloc/BoundaryTag.h:
+ (bmalloc::BoundaryTag::owner):
+ (bmalloc::BoundaryTag::setOwner):
+ (bmalloc::BoundaryTag::initSentinel):
+ (bmalloc::BoundaryTag::hasPhysicalPages): Deleted.
+ (bmalloc::BoundaryTag::setHasPhysicalPages): Deleted. Replaced the concept
+ of "has physical pages" with a bit indicating which heap owns the large
+ object. This is a more precise concept, since the old bit was really a
+ Yes / Maybe bit.
+
+ * bmalloc/Deallocator.cpp:
+
+ * bmalloc/FreeList.cpp: Adopt
+ (bmalloc::FreeList::takeGreedy):
+ (bmalloc::FreeList::take):
+ (bmalloc::FreeList::removeInvalidAndDuplicateEntries):
+ * bmalloc/FreeList.h:
+ (bmalloc::FreeList::push): Added API for considering the owner when
+ deciding if a free list entry is valid.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap): Adopt new API.
+
+ (bmalloc::Heap::scavengeLargeRanges): Scavenge all ranges with no minimum,
+ since some ranges might be able to merge with ranges in the VM heap, and
+ they won't be allowed to until we scavenge them.
+
+ (bmalloc::Heap::allocateSmallPage):
+ (bmalloc::Heap::allocateMediumPage):
+ (bmalloc::Heap::allocateLarge): New VM heap API makes this function
+ simpler, since we always get back physical pages now.
+
+ * bmalloc/Heap.h:
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::end):
+ (bmalloc::LargeObject::owner):
+ (bmalloc::LargeObject::setOwner):
+ (bmalloc::LargeObject::isValidAndFree):
+ (bmalloc::LargeObject::merge): Do not merge objects across heaps since
+ that causes madvise churn.
+ (bmalloc::LargeObject::validateSelf):
+ (bmalloc::LargeObject::init):
+ (bmalloc::LargeObject::hasPhysicalPages): Deleted.
+ (bmalloc::LargeObject::setHasPhysicalPages): Deleted. Propogate the Owner API.
+
+ * bmalloc/Owner.h: Added.
+
+ * bmalloc/SegregatedFreeList.cpp:
+ (bmalloc::SegregatedFreeList::SegregatedFreeList):
+ (bmalloc::SegregatedFreeList::insert):
+ (bmalloc::SegregatedFreeList::takeGreedy):
+ (bmalloc::SegregatedFreeList::take):
+ * bmalloc/SegregatedFreeList.h: Propogate the owner API.
+
+ * bmalloc/VMAllocate.h:
+ (bmalloc::vmDeallocatePhysicalPagesSloppy):
+ (bmalloc::vmAllocatePhysicalPagesSloppy): Clarified these functions and
+ removed an edge case.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::VMHeap):
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateSmallPage):
+ (bmalloc::VMHeap::allocateMediumPage):
+ (bmalloc::VMHeap::allocateLargeObject):
+ (bmalloc::VMHeap::deallocateLargeObject): Be sure to give each object
+ a new chance to merge, since it might have been prohibited from merging
+ before by virtue of not being in the VM heap.
+
+ (bmalloc::VMHeap::allocateLargeRange): Deleted.
+ (bmalloc::VMHeap::deallocateLargeRange): Deleted.
+
+2015-02-26 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Large object free list can grow infinitely
+ https://bugs.webkit.org/show_bug.cgi?id=142055
+
+ Reviewed by Andreas Kling.
+
+ By design, we don't eagerly remove large objects from the free list.
+ This creates two simple pathologies:
+
+ (1) If you free and then allocate the same object repeatedly, it will
+ duplicate itself in the free list repeatedly. Since it is never
+ invalid at the time of allocation, it will never be removed.
+
+ (2) If you split and then merge the same object repeatedly, it will
+ duplicate its split sibling in the free list repeatedly. If its
+ sibling is in a separate free list size class, it will never be
+ consulted at the time of allocation, so it will never be removed.
+
+ So, a simple "while (1) { free(malloc(x)); }" causes infinite memory
+ use in the free list.
+
+ The solution in this patch is a simple helper to remove garbage from the
+ free list if it grows too large. This pathology is not common, so the
+ cost is OK.
+
+ Long-term, perhaps we should rethink the laziness of these free lists.
+
+ * bmalloc/BoundaryTag.h:
+ (bmalloc::BoundaryTag::isMarked):
+ (bmalloc::BoundaryTag::setMarked): New bit, used by free list GC.
+
+ * bmalloc/FreeList.cpp:
+ (bmalloc::FreeList::removeInvalidAndDuplicateEntries): The GC algorithm.
+
+ * bmalloc/FreeList.h:
+ (bmalloc::FreeList::FreeList):
+ (bmalloc::FreeList::push): Invoke the GC if we're getting huge.
+
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::isMarked):
+ (bmalloc::LargeObject::setMarked):
+ (bmalloc::LargeObject::validateSelf): Expose the new bit.
+
+ * bmalloc/Sizes.h: New constant to control GC frequency.
+
+2015-02-26 Csaba Osztrogonác <os...@webkit.org>
+
+ URTBF after r180693.
+
+ * CMakeLists.txt:
+
+2015-02-26 Geoffrey Garen <gg...@apple.com>
+
+ Try to fix the Mac build.
+
+ Unreviewed.
+
+ * bmalloc.xcodeproj/project.pbxproj: Make FreeList.h available.
+
+2015-02-26 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Refactored SegregatedFreeList and BoundaryTag::init
+ https://bugs.webkit.org/show_bug.cgi?id=142049
+
+ Reviewed by Anders Carlsson.
+
+ Split out a FreeList class from SegregatedFreeList. This will make it
+ easier to add behaviors on free list insertion and removal -- and it's
+ probably how I should have designed things at the start.
+
+ Moved BoundaryTag::init into LargeObject, since all the related logic
+ lives in LargeObject now too, and this allows us to remove BoundaryTagInlines.h.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/BoundaryTagInlines.h: Removed.
+ * bmalloc/FreeList.cpp: Copied from Source/bmalloc/bmalloc/SegregatedFreeList.cpp.
+ (bmalloc::FreeList::takeGreedy):
+ (bmalloc::FreeList::take):
+ (bmalloc::SegregatedFreeList::SegregatedFreeList): Deleted.
+ (bmalloc::SegregatedFreeList::insert): Deleted.
+ (bmalloc::SegregatedFreeList::takeGreedy): Deleted.
+ (bmalloc::SegregatedFreeList::take): Deleted.
+ * bmalloc/FreeList.h: Copied from Source/bmalloc/bmalloc/SegregatedFreeList.h.
+ (bmalloc::FreeList::push):
+ * bmalloc/LargeObject.h:
+ (bmalloc::LargeObject::init):
+ * bmalloc/SegregatedFreeList.cpp:
+ (bmalloc::SegregatedFreeList::SegregatedFreeList):
+ (bmalloc::SegregatedFreeList::insert):
+ (bmalloc::SegregatedFreeList::takeGreedy):
+ (bmalloc::SegregatedFreeList::take):
+ * bmalloc/SegregatedFreeList.h:
+ * bmalloc/Sizes.h:
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::grow):
+
+2015-02-26 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: free up a bit in BoundaryTag
+ https://bugs.webkit.org/show_bug.cgi?id=142048
+
+ Reviewed by Brady Eidson.
+
+ We were wasting a bit by accident, and I need one now.
+
+ * bmalloc/Algorithm.h:
+ (bmalloc::rightShift): Deleted. Not needed, now that I've simplified
+ the math.
+
+ * bmalloc/BoundaryTag.h: Since each boundary tag bucket is 1024 bytes
+ long, the maximum offset into a bucket is 1023.
+
+ You need 5 bits to count up to 1024, but only 4 to count up to 1023.
+
+ Math is hard.
+
+ (bmalloc::BoundaryTag::compactBegin): Switched to division because it
+ is simpler, and easier to match up with our ASSERT. The compiler will
+ turn division by constant power of two into a shift for us.
+
+ (bmalloc::BoundaryTag::setRange): Added an ASSERT for compactBegin
+ because we do encode it, so we should ASSERT that encoding did not
+ lose information.
+
+ * bmalloc/Sizes.h: Shifting is no longer used since we use division
+ instead.
+
+2015-02-24 Stephanie Lewis <sl...@apple.com>
+
+ Rolling out http://trac.webkit.org/changeset/180430 as it causes the PLT to crash.
+ <rdar://problem/19948015>
+
+ Unreviewed.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::grow):
+ * bmalloc/VMHeap.h:
+ * bmalloc/Zone.cpp:
+ (bmalloc::Zone::Zone):
+ (bmalloc::Zone::size): Deleted.
+ * bmalloc/Zone.h:
+
+2015-02-24 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Added a little more abstraction for large objects
+ https://bugs.webkit.org/show_bug.cgi?id=141978
+
+ Reviewed by Sam Weinig.
+
+ Previously, each client needed to manage the boundary tags of
+ a large object using free functions. This patch introduces a LargeObject
+ class that does things a little more automatically.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::reallocate): Use the new LargeObject class.
+
+ * bmalloc/BeginTag.h:
+ (bmalloc::BeginTag::isInFreeList): Deleted. Moved this logic into the
+ LargeObject class.
+
+ * bmalloc/BoundaryTag.h:
+ (bmalloc::BoundaryTag::isSentinel):
+ (bmalloc::BoundaryTag::compactBegin):
+ (bmalloc::BoundaryTag::setRange):
+ (bmalloc::BoundaryTag::initSentinel): Added an explicit API for sentinels,
+ which we used to create and test for implicitly.
+
+ * bmalloc/BoundaryTagInlines.h:
+ (bmalloc::BoundaryTag::init):
+ (bmalloc::validate): Deleted.
+ (bmalloc::validatePrev): Deleted.
+ (bmalloc::validateNext): Deleted.
+ (bmalloc::BoundaryTag::mergeLeft): Deleted.
+ (bmalloc::BoundaryTag::mergeRight): Deleted.
+ (bmalloc::BoundaryTag::merge): Deleted.
+ (bmalloc::BoundaryTag::deallocate): Deleted.
+ (bmalloc::BoundaryTag::split): Deleted.
+ (bmalloc::BoundaryTag::allocate): Deleted. Moved this logic into the
+ LargeObject class.
+
+ * bmalloc/EndTag.h:
+ (bmalloc::EndTag::init):
+ (bmalloc::EndTag::operator=): Deleted. Re-reading this code, I found
+ special behavior in the assignment operator to be a surprising API.
+ So, I replaced the assignment operation with an explicit initializing
+ function.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::scavengeLargeRanges):
+ (bmalloc::Heap::allocateXLarge):
+ (bmalloc::Heap::findXLarge):
+ (bmalloc::Heap::deallocateXLarge):
+ (bmalloc::Heap::allocateLarge):
+ (bmalloc::Heap::deallocateLarge):
+ * bmalloc/Heap.h: No behavior changes here -- just adopting the
+ LargeObject interface.
+
+ * bmalloc/LargeObject.h: Added.
+ (bmalloc::LargeObject::operator!):
+ (bmalloc::LargeObject::begin):
+ (bmalloc::LargeObject::size):
+ (bmalloc::LargeObject::range):
+ (bmalloc::LargeObject::LargeObject):
+ (bmalloc::LargeObject::setFree):
+ (bmalloc::LargeObject::isFree):
+ (bmalloc::LargeObject::hasPhysicalPages):
+ (bmalloc::LargeObject::setHasPhysicalPages):
+ (bmalloc::LargeObject::isValidAndFree):
+ (bmalloc::LargeObject::merge):
+ (bmalloc::LargeObject::split):
+ (bmalloc::LargeObject::validateSelf):
+ (bmalloc::LargeObject::validate): Moved this code into a class, out of
+ BoundaryTag free functions.
+
+ New to the class are these features:
+
+ (1) Every reference to an object is validated upon creation and use.
+
+ (2) There's an explicit API for "This is a reference to an object
+ that might be stale (the DoNotValidate API)".
+
+ (3) The begin and end tags are kept in sync automatically.
+
+ * bmalloc/SegregatedFreeList.cpp:
+ (bmalloc::SegregatedFreeList::insert):
+ (bmalloc::SegregatedFreeList::takeGreedy):
+ (bmalloc::SegregatedFreeList::take):
+ * bmalloc/SegregatedFreeList.h: Adopt the LargeObject interface.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::grow):
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateLargeRange):
+ (bmalloc::VMHeap::deallocateLargeRange): Adopt the LargeObject interface.
+
+2015-02-20 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc should implement malloc introspection (to stop false-positive leaks when MallocStackLogging is off)
+ https://bugs.webkit.org/show_bug.cgi?id=141802
+
+ Reviewed by Andreas Kling.
+
+ Rolling back in with a fix for a crash seen while using GuardMalloc.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::grow):
+ * bmalloc/VMHeap.h:
+ * bmalloc/Zone.cpp: Re-land the old patch.
+
+ (bmalloc::Zone::size): Be sure to implement the size() function since
+ it's accessible indirectly via the malloc_zone_from_ptr public API --
+ and GuardMalloc calls it all the time.
+
+ (bmalloc::Zone::Zone):
+ * bmalloc/Zone.h: Re-land the old patch.
+
+2015-02-19 Commit Queue <co...@webkit.org>
+
+ Unreviewed, rolling out r180363.
+ https://bugs.webkit.org/show_bug.cgi?id=141814
+
+ Caused >50 crashes when running LayoutTests in GuardMalloc or
+ ASAN modes. (Requested by jernoble on #webkit).
+
+ Reverted changeset:
+
+ "bmalloc should implement malloc introspection (to stop false-
+ positive leaks when MallocStackLogging is off)"
+ https://bugs.webkit.org/show_bug.cgi?id=141802
+ http://trac.webkit.org/changeset/180363
+
+2015-02-19 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc should implement malloc introspection (to stop false-positive leaks when MallocStackLogging is off)
+ https://bugs.webkit.org/show_bug.cgi?id=141802
+
+ Reviewed by Andreas Kling.
+
+ Fixed a last-minute type.
+
+ The macro is OS, not PLATFORM.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::grow):
+ * bmalloc/VMHeap.h:
+ * bmalloc/Zone.h:
+
+2015-02-19 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc should implement malloc introspection (to stop false-positive leaks when MallocStackLogging is off)
+ https://bugs.webkit.org/show_bug.cgi?id=141802
+
+ Reviewed by Andreas Kling.
+
+ This patch does the bare minimum to stop false positive leaks from
+ being reported by the Darwin leaks tool. We register each super chunk
+ as a single object, and then request that the leaks tool scan it.
+
+ * bmalloc.xcodeproj/project.pbxproj: Added an abstraction for the malloc
+ zone introspection API.
+
+ * bmalloc/Algorithm.h: Missing #include.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::grow):
+ * bmalloc/VMHeap.h: Adopt the new abstraction.
+
+ * bmalloc/Zone.cpp: Added.
+ (bmalloc::remoteRead): Helper for reading an object out of another process.
+ (bmalloc::Zone::enumerator):
+ (bmalloc::Zone::Zone): Register a malloc zone so that we will participate
+ in introspection.
+
+ * bmalloc/Zone.h: Added.
+ (bmalloc::Zone::superChunks):
+ (bmalloc::Zone::addSuperChunk): Use a non-dynamically-allocated vector
+ since our dynamic allocations will not be scanned by leaks since they
+ will have the malloc VM tag.
+
+2015-02-18 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: VMHeap should keep a record of all of its VM ranges (for malloc introspection)
+ https://bugs.webkit.org/show_bug.cgi?id=141759
+
+ Reviewed by Andreas Kling.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/SuperChunk.h: Added.
+ (bmalloc::SuperChunk::create):
+ (bmalloc::SuperChunk::SuperChunk):
+ (bmalloc::SuperChunk::smallChunk):
+ (bmalloc::SuperChunk::mediumChunk):
+ (bmalloc::SuperChunk::largeChunk): Factored out super chunk creation
+ into a separate class, for clarity and type safety.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::grow):
+ (bmalloc::VMHeap::allocateSuperChunk): Renamed "allocateSuperChunk" to
+ "grow" because Andreas found "allocateSuperChunk" to be unclear.
+
+ * bmalloc/VMHeap.h: Track all our VM ranges. We will use this information
+ for malloc introspection.
+
+ (bmalloc::VMHeap::allocateSmallPage):
+ (bmalloc::VMHeap::allocateMediumPage):
+ (bmalloc::VMHeap::allocateLargeRange): Updated for renames.
+
+2015-02-18 Zan Dobersek <zd...@igalia.com>
+
+ Build bmalloc through CMake as a static library. It's then linked either
+ into the WTF library (if built as a shared library) or into the JSC and
+ WebKit2 libraries. There's no need to build it as a standalone shared library.
+
+ Rubber-stamped by Carlos Garcia Campos.
+
+ * CMakeLists.txt:
+
+2015-02-13 Gyuyoung Kim <gy...@samsung.com>
+
+ [BMalloc] Add a FIXME comment for memory alignas
+ https://bugs.webkit.org/show_bug.cgi?id=141556
+
+ Reviewed by Csaba Osztrogonác.
+
+ * bmalloc/Chunk.h: Add a FIXME comment.
+ * bmalloc/LargeChunk.h: ditto.
+
+2015-02-11 Csaba Osztrogonác <os...@webkit.org>
+
+ bmalloc buildfix on 32 bit Linux (x86/ARM)
+ https://bugs.webkit.org/show_bug.cgi?id=141472
+
+ Reviewed by Gyuyoung Kim.
+
+ * bmalloc/Algorithm.h:
+ (bmalloc::roundUpToMultipleOf):
+ * bmalloc/FixedVector.h:
+ (bmalloc::FixedVector::clear):
+ * bmalloc/Sizes.h:
+ (bmalloc::Sizes::sizeClass):
+
+2015-02-11 Gyuyoung Kim <gy...@samsung.com>
+
+ [EFL][GTK] Use bmalloc instead of tcmalloc
+ https://bugs.webkit.org/show_bug.cgi?id=140162
+
+ Reviewed by Carlos Garcia Campos.
+
+ Support to use bmalloc on EFL and GTK ports.
+
+ * CMakeLists.txt: Added.
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::allocate):
+ Fix unused return value caused by posix_memalign().
+ * bmalloc/AsyncTask.h:
+ * bmalloc/BoundaryTag.h:
+ (bmalloc::BoundaryTag::clear):
+ * bmalloc/Chunk.h:
+ Change Traits::Page with Traits::PageType in order to fix
+ -fpermitive build error on EFL and GTK port.
+ * bmalloc/EndTag.h:
+ (bmalloc::EndTag::operator=):
+ * bmalloc/Line.h: ditto.
+ * bmalloc/MediumTraits.h:
+ * bmalloc/Page.h: ditto.
+ * bmalloc/PerThread.h:
+ EFL port doesn't support __has_include definition yet.
+ Define HAVE_PTHREAD_MACHDEP_H according to check if __has_include is supported.
+ * bmalloc/SmallTraits.h: ditto.
+ * bmalloc/VMAllocate.h:
+ (bmalloc::vmDeallocatePhysicalPages):
+ (bmalloc::vmAllocatePhysicalPages):
+ * bmalloc/Vector.h:
+ (bmalloc::Vector<T>::push):
+ (bmalloc::Vector<T>::reallocateBuffer):
+
+2015-01-31 Sam Weinig <sa...@webkit.org>
+
+ Remove even more Mountain Lion support
+ https://bugs.webkit.org/show_bug.cgi?id=141124
+
+ Reviewed by Alexey Proskuryakov.
+
+ * Configurations/Base.xcconfig:
+ * Configurations/DebugRelease.xcconfig:
+
+2015-01-30 Geoffrey Garen <gg...@apple.com>
+
+ GC marking threads should clear malloc caches
+ https://bugs.webkit.org/show_bug.cgi?id=141097
+
+ Reviewed by Andreas Kling.
+
+ Split the scavenging API into per-thread vs global, so that you can
+ request to scavenge your own thread without scavenging the whole heap.
+
+ * bmalloc/Cache.cpp:
+ (bmalloc::Cache::scavenge):
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::scavengeThisThread):
+ (bmalloc::api::scavenge):
+
+2015-01-28 Dana Burkart <db...@apple.com>
+
+ Move ASan flag settings from DebugRelease.xcconfig to Base.xcconfig
+ https://bugs.webkit.org/show_bug.cgi?id=136765
+
+ Reviewed by Alexey Proskuryakov.
+
+ * Configurations/Base.xcconfig:
+ * Configurations/DebugRelease.xcconfig:
+
+2015-01-21 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: support aligned allocation
+ https://bugs.webkit.org/show_bug.cgi?id=140732
+
+ Reviewed by Andreas Kling.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::allocate): New function for aligned allocation.
+
+ Small and medium requests just allocate and free until they find an
+ aligned pointer. This is slightly inefficient in the worst case, but
+ still constant-time with little-to-no space overhead.
+
+ Large requests use a new API that requires the client to specify both
+ its ideal size and alignment, and the worst-case size you would have to
+ allocate in order to produce some interior pointer of the requested size
+ and alignment. We put the burden of this calculation on the client
+ because it simplifies things if we guarantee that allocation won't fail.
+
+ XLarge requests are easy: we just forward them to vmAllocate, which
+ already supported aligned requests.
+
+ * bmalloc/BoundaryTag.h:
+ * bmalloc/BoundaryTagInlines.h:
+ (bmalloc::BoundaryTag::mergeLeft):
+ (bmalloc::BoundaryTag::mergeRight):
+ (bmalloc::BoundaryTag::merge):
+ (bmalloc::BoundaryTag::deallocate):
+ (bmalloc::BoundaryTag::split):
+ (bmalloc::BoundaryTag::allocate): No behavior change here. I just
+ refactored the interface to remove some reference out parameters in
+ order to clarify what changes and what doesn't.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateXLarge): Added an alignment API.
+
+ (bmalloc::Heap::allocateLarge):
+ * bmalloc/Heap.h: Added an alignment API. I split out allocateLarge into
+ a few variants, so aligned and unaligned allocation could share some code.
+
+ * bmalloc/SegregatedFreeList.cpp:
+ (bmalloc::SegregatedFreeList::take):
+ * bmalloc/SegregatedFreeList.h: Changed to use a separate, explicit API
+ for aligned allocation. It turns out that the aligned path is pretty
+ different, since it ends up searching for two potential ways to satisfy
+ an allocation: either large enough and aligned, or large enough to split
+ into something not aligned and something large enough and aligned.
+
+ * bmalloc/VMAllocate.h:
+ (bmalloc::vmAllocate): Switched alignment to come before size because
+ that's how the memalign API specifies it.
+
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateLargeRange): Added an alignment API.
+
+2015-01-20 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: a little bit of cleanup
+ https://bugs.webkit.org/show_bug.cgi?id=140687
+
+ Reviewed by Anders Carlsson.
+
+ * bmalloc/Algorithm.h:
+ (bmalloc::isPowerOfTwo): Added a check for 0, since 0 would break a lot
+ of code.
+
+ * bmalloc/BoundaryTag.h:
+ * bmalloc/BoundaryTagInlines.h:
+ (bmalloc::BoundaryTag::mergeLeft):
+ (bmalloc::BoundaryTag::mergeRight):
+ (bmalloc::BoundaryTag::merge):
+ (bmalloc::BoundaryTag::deallocate):
+ (bmalloc::BoundaryTag::split):
+ (bmalloc::BoundaryTag::allocate):
+ (bmalloc::BoundaryTag::mergeLargeLeft): Deleted.
+ (bmalloc::BoundaryTag::mergeLargeRight): Deleted.
+ (bmalloc::BoundaryTag::mergeLarge): Deleted.
+ (bmalloc::BoundaryTag::splitLarge): Deleted. Removed the word "Large"
+ from all these functions, since boundary tags always pertain to large
+ objects, and putting the word "Large" everywhere wasn't helping to
+ explain that.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateXLarge):
+ (bmalloc::Heap::findXLarge):
+ (bmalloc::Heap::deallocateXLarge):
+ * bmalloc/Heap.h:
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateXLarge): Deleted.
+ (bmalloc::VMHeap::findXLarge): Deleted.
+ (bmalloc::VMHeap::deallocateXLarge): Deleted. Moved XLarge allocation
+ from VMHeap to Heap. Since the purpose of the VMHeap is to cache VM
+ ranges, and the VMHeap never caches any XLarge ranges, it doesn't
+ really make sense for the VMHeap to be involved.
+
+2015-01-16 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: refactored XLarge allocation for better alignment
+ https://bugs.webkit.org/show_bug.cgi?id=140582
+
+ Reviewed by Andreas Kling.
+
+ XLarge objects used to be Large objects with an extra bit of metadata
+ that said "actually, I'm not large -- I'm extra large".
+
+ The metadata header in an XLarge allocation made it impossible for the
+ XLarge object to honor a very large alignment request.
+
+ The solution is to stop using a metadata header for XLarge objects, and
+ instead to store explicit metadata on the side.
+
+ This is a bit less astonishing, which is also nice.
+
+ Finding XLarge metadata is now a linear search. That's probably OK, since
+ it was always so in TCMalloc, and the usual number of XLarge allocations
+ in a process is 0.
+
+ This design makes it possible for the heap to cache XLarge allocations
+ with and/or without physical pages. I haven't actually done that yet
+ because the tradeoffs are subtle, so I don't want to do anything without
+ a motivating test case.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::reallocate): Removed the concept of an XLargeChunk,
+ since an XLarge allocation is now just a naked buffer without a header.
+
+ (bmalloc::Allocator::allocateXLarge): Added an explicit qualifier for
+ XLarge alignment, since XLargeChunk won't give this to us implicitly
+ anymore.
+
+ * bmalloc/BoundaryTag.h:
+ (bmalloc::BoundaryTag::setRange):
+ (bmalloc::BoundaryTag::isXLarge): Deleted.
+ (bmalloc::BoundaryTag::setXLarge): Deleted.
+ * bmalloc/BoundaryTagInlines.h:
+ (bmalloc::validate):
+ (bmalloc::BoundaryTag::deallocate): Removed the XLarge hacks from Large allocations.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::deallocateXLarge):
+ (bmalloc::Deallocator::deallocateSlowCase):
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::findXLarge):
+ (bmalloc::Heap::allocateXLarge):
+ (bmalloc::Heap::deallocateXLarge):
+ * bmalloc/Heap.h: Updated for interface changes.
+
+ * bmalloc/ObjectType.cpp:
+ (bmalloc::objectType):
+ * bmalloc/ObjectType.h:
+ (bmalloc::isXLarge): We can now tell if a pointer is XLarge just by
+ examining its bit pattern -- just like we do for other kinds of
+ allocations -- which is nice.
+
+ * bmalloc/Sizes.h:
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateXLarge):
+ (bmalloc::VMHeap::findXLarge):
+ (bmalloc::VMHeap::deallocateXLarge): Keep an explicit vector of metadata
+ for XLarge allocations.
+
+ * bmalloc/XLargeChunk.h: Removed.
+
+2015-01-16 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: added some infrastructure for aligned allocation
+ https://bugs.webkit.org/show_bug.cgi?id=140572
+
+ Reviewed by Andreas Kling.
+
+ * bmalloc/Algorithm.h:
+ (bmalloc::isPowerOfTwo):
+ (bmalloc::roundUpToMultipleOf):
+ (bmalloc::roundDownToMultipleOf): Refactored some duplicate code to use our
+ isPowerOfTwo helper function.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::allocate):
+ * bmalloc/Allocator.h: Stubbed out an implementation of aligned allocation.
+ Doesn't do anything yet, but does correctly forward to system malloc
+ when bmalloc is disabled.
+
+ * bmalloc/Cache.cpp:
+ (bmalloc::Cache::allocateSlowCaseNullCache):
+ * bmalloc/Cache.h:
+ (bmalloc::Cache::allocate):
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::memalign):
+ * bmalloc/mbmalloc.cpp: Stubbed out an API for aligned allocation.
+
+2015-01-13 Geoffrey Garen <gg...@apple.com>
+
+ Consider alignment when allocating from a SegregatedFreeList
+ https://bugs.webkit.org/show_bug.cgi?id=140408
+
+ Reviewed by Sam Weinig.
+
+ In preparation for supporting aligned allocation.
+
+ No performance change.
+
+ Since this is just one extra branch in an already expensive function,
+ I decided not to duplicate the function just to avoid the branch in
+ the un-aligned case.
+
+ * bmalloc/SegregatedFreeList.cpp:
+ (bmalloc::SegregatedFreeList::take):
+ * bmalloc/SegregatedFreeList.h:
+
+2015-01-13 Geoffrey Garen <gg...@apple.com>
+
+ Renamed minimum to size in SegregatedFreeList
+ https://bugs.webkit.org/show_bug.cgi?id=140406
+
+ Reviewed by Sam Weinig.
+
+ In preparation for supporting aligned allocation.
+
+ * bmalloc/SegregatedFreeList.cpp:
+ (bmalloc::SegregatedFreeList::takeGreedy):
+ (bmalloc::SegregatedFreeList::take): Every size passed to malloc is
+ really just a minimum. Let's not imply that this value is special.
+
+2015-01-11 Dan Bernstein <mi...@apple.com>
+
+ Geoff is organized, but he is not an organization.
+
+ Rubber-stamped by Anders Carlsson.
+
+ * bmalloc.xcodeproj/project.pbxproj: Removed the ORGANIZATIONNAME project attribute.
+
+2015-01-07 Geoffrey Garen <gg...@apple.com>
+
+ Make bmalloc work with ASan
+ https://bugs.webkit.org/show_bug.cgi?id=140194
+
+ Reviewed by Mark Lam.
+
+ * bmalloc/BPlatform.h: Added a way to detect Darwin OSes, since we need
+ an OS-specific API to test for loaded runtime libraries.
+
+ * bmalloc/Environment.cpp:
+ (bmalloc::isASanEnabled):
+ (bmalloc::Environment::computeIsBmallocEnabled): Disabled bmalloc if
+ ASan is enabled, since system malloc has the Asan hooks we need.
+
+ You could check for the ASan compile-time flag instead, but doing this
+ check at runtime prepares bmalloc for a world where it is a dynamic
+ library that might be loaded into projects it did not compile with.
+
+2015-01-05 Geoffrey Garen <gg...@apple.com>
+
+ Fix up bmalloc's PerThread for use on Linux
+ https://bugs.webkit.org/show_bug.cgi?id=139804
+
+ Reviewed by Anders Carlsson.
+
+ The previous implementation was a bit slow.
+
+ * bmalloc/PerThread.h:
+ (bmalloc::PerThreadStorage<Cache>::get):
+ (bmalloc::PerThreadStorage::get):
+ (bmalloc::PerThreadStorage::init): Added a catch-all cross-platform Unix
+ way to do fast per-thread access without taking a lock every time. This
+ probably works on all the platforms we care about, and it matches other
+ techniques we use elsewhere in WebKit.
+
+ (bmalloc::PerThread<T>::getFastCase): Removed the conditional from
+ this class because PerThreadStorage now encapsulates everything that
+ needs to be conditional.
+
+ (bmalloc::PerThreadStorage::initSharedKeyIfNeeded): Deleted.
+
+2014-12-26 Dan Bernstein <mi...@apple.com>
+
+ <rdar://problem/19348208> REGRESSION (r177027): iOS builds use the wrong toolchain
+ https://bugs.webkit.org/show_bug.cgi?id=139950
+
+ Reviewed by David Kilzer.
+
+ * Configurations/Base.xcconfig: Only define TOOLCHAINS when building for OS X, doing so
+ in a manner that works with Xcode 5.1.1.
+
+2014-12-15 Geoffrey Garen <gg...@apple.com>
+
+ Safari crashes when you set Malloc environment variables
+ https://bugs.webkit.org/show_bug.cgi?id=139656
+
+ Reviewed by Michael Saboff.
+
+ I forgot to cover the realloc() case. Whoops. (OoPS?)
+
+ This time around, I ran the full MallocBench test suite in Malloc=1
+ mode, and it passed.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::reallocate):
+ * bmalloc/Allocator.h: Pushed realloc() logic down into the allocator.
+ It needs to be down there so that we can do the short-circuiting check
+ for whether bmalloc is enabled first.
+
+ Also added the check.
+
+ * bmalloc/Cache.cpp:
+ (bmalloc::Cache::scavenge):
+ (bmalloc::Cache::Cache):
+ (bmalloc::Cache::reallocateSlowCaseNullCache):
+ * bmalloc/Cache.h:
+ (bmalloc::Cache::deallocator):
+ (bmalloc::Cache::reallocate): Ditto.
+
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::free):
+ (bmalloc::api::realloc): Ditto.
+
+ (bmalloc::api::scavenge): Pushed this down into Cache to match the
+ surrounding functions.
+
+2014-12-11 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc should support system memory analysis tools (part 2)
+ https://bugs.webkit.org/show_bug.cgi?id=139565
+
+ Reviewed by Mark Lam.
+
+ This patch actually queries the environment to see if memory analysis
+ tools have been enabled.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::scavenge): Don't process the object log if
+ we've disabled bmalloc because it will be full of invalid nullptrs.
+
+ * bmalloc/Environment.cpp:
+ (bmalloc::isMallocEnvironmentVariableSet): Test for the list of known
+ Malloc debugging flags. I also added a plain "Malloc" catch-all for
+ when you want to disable bmalloc without enabling any kind of funny
+ business.
+
+ It would be slightly nicer just to iterate the list of environment
+ variables and strstr them, but getenv is the more portable option,
+ and performance here doesn't really matter.
+
+ (bmalloc::isLibgmallocEnabled): Test for the libgmalloc insertion
+ environment variable.
+
+ (bmalloc::Environment::computeIsBmallocEnabled):
+
+2014-12-11 Geoffrey Garen <gg...@apple.com>
+
+ Try to fix the iOS simulator build.
+
+ #include the declaration of malloc / free.
+
+ * bmalloc/Allocator.cpp:
+ * bmalloc/Deallocator.cpp:
+
+2014-12-11 Geoffrey Garen <gg...@apple.com>
+
+ Try to fix the build.
+
+ * bmalloc.xcodeproj/project.pbxproj: Marked a header exported.
+
+2014-12-11 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc should support system memory analysis tools (part 1)
+ https://bugs.webkit.org/show_bug.cgi?id=139559
+
+ Reviewed by Mark Lam.
+
+ This patch adds the hooks to disable bmalloc at runtime if certain
+ environment variables are set, but doesn't actually read from the
+ environment yet.
+
+ No performance change.
+
+ * bmalloc.xcodeproj/project.pbxproj: Added the Environment class, which
+ we'll use to read environment variables and see if memory analysis tools
+ have been enabled.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::Allocator):
+ (bmalloc::Allocator::allocateSlowCase): Added a hook to disable bmalloc
+ on the allocation path. We cache the setting to make the check fast.
+
+ * bmalloc/Allocator.h: Interface changes.
+
+ * bmalloc/Cache.cpp:
+ (bmalloc::Cache::Cache): Pass a heap pointer through to our allocator
+ and deallocator. This main purpose is to enable them to query the
+ environment for whether bmalloc is enabled; but this is also a slightly
+ cleaner way to guarantee to them that the Heap has been pre-initialized.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::Deallocator): If bmalloc is disable, artificially
+ fill the object log to force us to take the slow path on all deallocations.
+
+ (bmalloc::Deallocator::deallocateSlowCase): Do the disabled check.
+
+ * bmalloc/Deallocator.h: Interface changes.
+
+ * bmalloc/Environment.cpp: Added.
+ (bmalloc::Environment::Environment):
+ (bmalloc::Environment::computeIsBmallocEnabled):
+ * bmalloc/Environment.h: Added.
+ (bmalloc::Environment::isBmallocEnabled): This is the class that will
+ encapsulate looking for environment variables that turn on heap
+ analysis tools.
+
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::environment):
+
+ * bmalloc/Mutex.h:
+ (bmalloc::Mutex::Mutex):
+ * bmalloc/StaticMutex.h: A little refactoring to clarify these comments,
+ since I got super confused about them while writing this patch.
+
+ * bmalloc/VMHeap.cpp: Fixed an #include.
+
+2014-12-09 David Kilzer <dd...@apple.com>
+
+ Switch from using PLATFORM_NAME to SDK selectors in ANGLE, bmalloc, gtest, JavaScriptCore, WTF
+ <http://webkit.org/b/139212>
+
+ Reviewed by Joseph Pecoraro.
+
+ * Configurations/Base.xcconfig:
+ - Only set GCC_ENABLE_OBJC_GC, GCC_MODEL_TUNING and TOOLCHAINS
+ on OS X.
+ * Configurations/DebugRelease.xcconfig:
+ - Only set MACOSX_DEPLOYMENT_TARGET and SDKROOT on OS X.
+
+2014-11-07 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc uses 8X more virtual memory than necessary
+ https://bugs.webkit.org/show_bug.cgi?id=138495
+
+ Reviewed by Mark Lam.
+
+ iOS has a per-process virtual memory cap around 1GB, so there's some
+ value to not going totally ham with virtual memory.
+
+ We currently use about 8X the necessary amount:
+ - 2X to align our VM allocation
+ - 4X to reserve small / medium / (2) large chunk VM ranges per superchunk
+
+ We can cut that down:
+ - Return the unaligned portion of our VM allocation (-2X)
+ - Use all the chunks in a superchunk, instead of allocating one
+ chunk per superchunk (-4X)
+
+ * bmalloc/Algorithm.h:
+ (bmalloc::roundUpToMultipleOf): Added a non-constant version of this
+ function so we can call it with getpagesize() at runtime.
+
+ * bmalloc/Chunk.h:
+ * bmalloc/LargeChunk.h:
+ (bmalloc::LargeChunk::create): Deleted. Instead of each chunk allocating
+ its own VM, VMHeap allocates the superchunk and all the chunks in it at a time.
+
+ * bmalloc/VMAllocate.h:
+ (bmalloc::vmValidate):
+ (bmalloc::vmAllocate): ASSERT that mmap succeeds to make crashes clearer
+ if it does not succeed. Allocate precisely, and give back the extra.
+
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::allocateSuperChunk):
+ (bmalloc::VMHeap::allocateSmallChunk): Deleted.
+ (bmalloc::VMHeap::allocateMediumChunk): Deleted.
+ (bmalloc::VMHeap::allocateLargeChunk): Deleted. Use all the chunks
+ in a superchunk, instead of just one.
+
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateSmallPage):
+ (bmalloc::VMHeap::allocateMediumPage):
+ (bmalloc::VMHeap::allocateLargeRange):
+ * bmalloc/XLargeChunk.h:
+ (bmalloc::XLargeChunk::create): Updated to match changes above.
+
+2014-11-01 David Kilzer <dd...@apple.com>
+
+ JavaScriptCore is missing debug info for bmalloc because libbmalloc.a is stripped
+ <https://webkit.org/b/138286>
+ <rdar://problem/18847087>
+
+ Reviewed by Dan Bernstein.
+
+ * Configurations/bmalloc.xcconfig: Set STRIP_INSTALLED_PRODUCT
+ to NO for the target that produces libbmalloc.a so that the
+ debug symbols will be linked into JavaScriptCore and end up in
+ its dSYM file.
+
+2014-10-30 Dana Burkart <db...@apple.com>
+
+ <rdar://problem/18821260> Prepare for the mysterious future
+
+ Reviewed by Lucas Forschler.
+
+ * Configurations/Base.xcconfig:
+ * Configurations/DebugRelease.xcconfig:
+
+2014-09-24 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: cleaned up fast path vs slow path
+ https://bugs.webkit.org/show_bug.cgi?id=137081
+
+ Reviewed by Sam Weinig.
+
+ Might be a 1% speedup on MallocBench. Also cleans up the code a bit.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::Allocator): Merged the small and medium range
+ caches, just like the small and medium allocators. Ranges are abstract
+ objects that don't really care whether they hold small or medium objects,
+ so they don't need to be segregated.
+
+ (bmalloc::Allocator::scavenge): Ditto.
+
+ (bmalloc::Allocator::allocateBumpRangeSlowCase):
+ (bmalloc::Allocator::allocateBumpRange): Same thing here, except that
+ we do care a tiny bit, because we need to specify small vs medium when
+ allocating new ranges from the heap, to ensure that the heap allocates
+ from the right segment of VM.
+
+ (bmalloc::Allocator::allocateLarge):
+ (bmalloc::Allocator::allocateXLarge): NO_INLINE because this was clouding
+ up the fast path. Large allocation performance is dominated by allocation
+ logic and initialization, so inlining it doesn't help.
+
+ (bmalloc::Allocator::allocateSlowCase): Slow path got a bit cleaner since
+ it doesn't need to distinguish small vs medium objects.
+
+ (bmalloc::Allocator::allocateSmallBumpRange): Deleted.
+ (bmalloc::Allocator::allocateMediumBumpRange): Deleted.
+
+ * bmalloc/Allocator.h:
+ * bmalloc/BumpRange.h:
+
+ * bmalloc/Cache.cpp:
+ (bmalloc::Cache::allocateSlowCase): Deleted.
+ (bmalloc::Cache::deallocateSlowCase): Deleted.
+ * bmalloc/Cache.h:
+ (bmalloc::Cache::allocate):
+ (bmalloc::Cache::deallocate):
+ (bmalloc::Cache::allocateFastCase): Deleted.
+ (bmalloc::Cache::deallocateFastCase): Deleted. Removed the Cache slow
+ paths. The downside to this change is that the fast path branches to two
+ distinct failure cases instead of one. The upside is that the slow path
+ doesn't need to re-read the segment register, which is not as cheap as a
+ normal register, and it doesn't need to do an extra level of function
+ call. Seems to be worth it.
+
+ * bmalloc/Deallocator.h:
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::refillSmallBumpRangeCache):
+ (bmalloc::Heap::refillMediumBumpRangeCache):
+ * bmalloc/Heap.h: Updated for interface changes.
+
+ * bmalloc/Sizes.h: The most ranges a cache will hold is the number of
+ small lines in a page / 2, since any other free lines will coalesce
+ with their neighbors.
+
+2014-09-23 Geoffrey Garen <gg...@apple.com>
+
+ Rolled out r173346.
+
+ bmalloc should honor the FastMalloc statistics API
+ https://bugs.webkit.org/show_bug.cgi?id=136592
+
+ This didn't really work. Because we allow ranges with and without
+ physical pages to merge, and we allow double-committing and
+ double-decommitting, we can't rely on commit actions to track memory
+ footprint.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::size): Deleted.
+ (bmalloc::Heap::capacity): Deleted.
+ * bmalloc/Heap.h:
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::VMHeap):
+ (bmalloc::VMHeap::allocateSmallChunk):
+ (bmalloc::VMHeap::allocateMediumChunk):
+ (bmalloc::VMHeap::allocateLargeChunk):
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateSmallPage):
+ (bmalloc::VMHeap::allocateMediumPage):
+ (bmalloc::VMHeap::allocateLargeRange):
+ (bmalloc::VMHeap::deallocateSmallPage):
+ (bmalloc::VMHeap::deallocateMediumPage):
+ (bmalloc::VMHeap::deallocateLargeRange):
+ (bmalloc::VMHeap::size): Deleted.
+ (bmalloc::VMHeap::capacity): Deleted.
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::heapSize): Deleted.
+ (bmalloc::api::heapCapacity): Deleted.
+
+2014-09-23 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Allocation should be more precise
+ https://bugs.webkit.org/show_bug.cgi?id=136993
+
+ Reviewed by Gavin Barraclough.
+
+ 13% reduction in heap size on the MallocBench *_memory_warning benchmarks.
+
+ This patch teaches the allocator to merge adjacent free lines into a
+ single allocatable range. This allows us to shrink the size of an
+ individual line without increasing fragmentation or the rate of allocator
+ slow paths.
+
+ We'll only take more slow paths when available memory is sparse, which
+ is exactly when it's worth it. When available memory is dense, we'll
+ take fewer slow paths.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/Algorithm.h:
+ (bmalloc::divideRoundingUp):
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::Allocator): Updated for interface changes.
+
+ (bmalloc::Allocator::scavenge): Scavenge by object instead of by line.
+ Now that we merge lines, it's not convenient to scavenge by line.
+
+ (bmalloc::Allocator::allocateSmallBumpRange):
+ (bmalloc::Allocator::allocateMediumBumpRange): Allocate whole ranges
+ instead of individual lines.
+
+ (bmalloc::Allocator::allocateSlowCase):
+ (bmalloc::Allocator::allocateSmallLine): Deleted.
+ (bmalloc::Allocator::allocateMediumLine): Deleted.
+ (bmalloc::Allocator::allocateMedium): Deleted.
+ * bmalloc/Allocator.h:
+ (bmalloc::Allocator::allocateFastCase): Folded medium allocations
+ into the standard fast path with small allocations. Since a BumpAllocator
+ just allocates out of an arbitrary range, it doesn't need to distinguish
+ between small and medium lines.
+
+ * bmalloc/BumpAllocator.h:
+ (bmalloc::BumpAllocator::size):
+ (bmalloc::BumpAllocator::BumpAllocator):
+ (bmalloc::BumpAllocator::init):
+ (bmalloc::BumpAllocator::refill):
+ (bmalloc::BumpAllocator::line): Deleted. No need to track line information
+ anymore: the heap just gives us a pointer and a pre-computed number of
+ objects, and we allocate them.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::processObjectLog): Updated for interface changes.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap):
+ (bmalloc::Heap::initializeLineMetadata): Pre-compute precise metadata
+ detailing where all objects will lie in memory. After we merge two lines,
+ we might allocate an object that spans from one line to the next. This
+ metadata details which bits of memory overlap in that way, and how they
+ overlap.
+
+ (bmalloc::Heap::refillSmallBumpRangeCache):
+ (bmalloc::Heap::refillMediumBumpRangeCache): Scan a whole page at a time,
+ and merge adjacent free lines into BumpRanges.
+
+ (bmalloc::Heap::allocateSmallPage):
+ (bmalloc::Heap::allocateMediumPage):
+ (bmalloc::Heap::deallocateSmallLine):
+ (bmalloc::Heap::deallocateMediumLine): Track pages rather than lines,
+ since we scan for free memory a page at a time.
+
+ (bmalloc::Heap::allocateSmallLineSlowCase): Deleted.
+ (bmalloc::Heap::allocateMediumLineSlowCase): Deleted. Folded into the
+ fast path.
+
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::derefSmallLine):
+ (bmalloc::Heap::derefMediumLine):
+ (bmalloc::Heap::deallocateSmallLine): Deleted.
+ (bmalloc::Heap::allocateSmallLine): Deleted.
+ (bmalloc::Heap::deallocateMediumLine): Deleted.
+ (bmalloc::Heap::allocateMediumLine): Deleted. Updated for interface changes.
+
+ * bmalloc/Line.h:
+ (bmalloc::Line<Traits>::ref):
+ (bmalloc::Line<Traits>::deref):
+ (bmalloc::Line<Traits>::concurrentRef): Deleted. We don't pass a derefCount
+ anymore, since we only ever deref by 1 now.
+
+ * bmalloc/MediumAllocator.h:
+ (bmalloc::MediumAllocator::isNull): Deleted.
+ (bmalloc::MediumAllocator::MediumAllocator): Deleted.
+ (bmalloc::MediumAllocator::line): Deleted.
+ (bmalloc::MediumAllocator::allocate): Deleted.
+ (bmalloc::MediumAllocator::derefCount): Deleted.
+ (bmalloc::MediumAllocator::refill): Deleted.
+ (bmalloc::MediumAllocator::clear): Deleted. Deleted some code that's
+ been dead for a while, since it doesn't build anymore with this patch.
+
+ * bmalloc/Page.h:
+ (bmalloc::Page::sizeClass):
+ (bmalloc::Page::setSizeClass):
+ (bmalloc::Page::smallSizeClass): Deleted.
+ (bmalloc::Page::setSmallSizeClass): Deleted. Renamed setSmallSizeClass
+ to sizeClass, since we use it for medium sizes too.
+
+ * bmalloc/Sizes.h:
+ (bmalloc::Sizes::sizeClass):
+ (bmalloc::Sizes::objectSize): Shrank line sizes to save memory.
+
+ (bmalloc::Sizes::smallSizeClassFor): Deleted.
+ (bmalloc::Sizes::mediumSizeClassFor): Deleted.
+
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::realloc): Now that we have precise objects sizes, realloc
+ can be a bit more precise. It also has to be, since we can't guarantee
+ that an object ends at the end of a line anymore.
+
+2014-09-19 Daniel Bates <da...@apple.com>
+
+ Always assume internal SDK when building configuration Production
+ https://bugs.webkit.org/show_bug.cgi?id=136925
+ <rdar://problem/18362399>
+
+ Reviewed by Dan Bernstein.
+
+ * Configurations/Base.xcconfig:
+
+2014-09-16 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: moved line caches from the deallocator to the allocator
+ https://bugs.webkit.org/show_bug.cgi?id=136868
+
+ Reviewed by Gavin Barraclough.
+
+ I did this mostly as a simplification, to make it easier to change the
+ allocation strategy.
+
+ No throughput change on MallocBench. Saves about 50kB.
+
+ Since the deallocator needs to lock the heap when freeing lines anyway,
+ there isn't much benefit to giving the deallocator a local cache of
+ deallocated lines.
+
+ We still give the allocator a local cache of lines because that does
+ reduce the frequency at which it needs to lock the heap in order to
+ acquire more lines.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::scavenge):
+ (bmalloc::Allocator::allocateSmallLine):
+ (bmalloc::Allocator::allocateMediumLine):
+ (bmalloc::Allocator::allocateMedium):
+ (bmalloc::Allocator::allocateSlowCase):
+ * bmalloc/Allocator.h:
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::Deallocator):
+ (bmalloc::Deallocator::scavenge):
+ (bmalloc::Deallocator::processObjectLog):
+ (bmalloc::Deallocator::deallocateSmallLine): Deleted.
+ (bmalloc::Deallocator::allocateSmallLine): Deleted.
+ (bmalloc::Deallocator::deallocateMediumLine): Deleted.
+ (bmalloc::Deallocator::allocateMediumLine): Deleted.
+ * bmalloc/Deallocator.h:
+
+ * bmalloc/Sizes.h:
+ * bmalloc/VMAllocate.h: Took the opportunity to make the line cache size
+ exactly one page in size. That's about what we were shooting for anyway,
+ and it may make it easier to switch to per-page allocation in future.
+
+2014-09-15 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: allocate small and medium objects using the same bump pointer class
+ https://bugs.webkit.org/show_bug.cgi?id=136843
+
+ Reviewed by Gavin Barraclough.
+
+ 4% speedup on MallocBench.
+
+ Now that medium-sized objects have dedicated per-size allocators, they
+ don't need to use an arbitrary bump pointer allocator. This means that
+ every allocator knows how many objects it will allocate from the start,
+ and we don't need a post-processing step to adjust refcounts based on
+ real allocation count.
+
+ * bmalloc.xcodeproj/project.pbxproj: Renamed SmallAllocator to BumpAllocator
+ since it's used for small and medium objects now.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::Allocator): Updated to use new interface.
+ (bmalloc::Allocator::scavenge): To "retire" an allocator, we just need
+ to make sure that we finish allocating all the objects in it.
+
+ (bmalloc::Allocator::allocateMedium):
+ (bmalloc::Allocator::allocateSlowCase):
+ (bmalloc::Allocator::retire): Deleted.
+ (bmalloc::Allocator::processSmallAllocatorLog): Deleted.
+ (bmalloc::Allocator::processMediumAllocatorLog): Deleted.
+ * bmalloc/Allocator.h:
+ (bmalloc::Allocator::allocateFastCase): Removed abstractions and data
+ used to post-process an allocator based on how many objects it allocated.
+
+ * bmalloc/BumpAllocator.h: Copied from Source/bmalloc/bmalloc/SmallAllocator.h.
+ (bmalloc::BumpAllocator::BumpAllocator):
+ (bmalloc::BumpAllocator::init):
+ (bmalloc::BumpAllocator::line):
+ (bmalloc::BumpAllocator::validate):
+ (bmalloc::BumpAllocator::allocate):
+ (bmalloc::BumpAllocator::refill):
+ (bmalloc::BumpAllocator::clear): Updated these functions to be agnostic
+ about the kinds of lines they allocate into. In some cases, the line
+ type must be provided as a template parameter by the caller.
+
+ (bmalloc::SmallAllocator::SmallAllocator): Deleted.
+ (bmalloc::SmallAllocator::line): Deleted.
+ (bmalloc::SmallAllocator::allocate): Deleted.
+ (bmalloc::SmallAllocator::objectCount): Deleted.
+ (bmalloc::SmallAllocator::derefCount): Deleted.
+ (bmalloc::SmallAllocator::refill): Deleted.
+ (bmalloc::SmallAllocator::clear): Deleted.
+
+ * bmalloc/ObjectType.h:
+ (bmalloc::isMedium):
+
+ * bmalloc/SmallAllocator.h:
+ (bmalloc::SmallAllocator::isNull): Deleted.
+ (bmalloc::SmallAllocator::canAllocate): Deleted.
+ (bmalloc::SmallAllocator::SmallAllocator): Deleted.
+ (bmalloc::SmallAllocator::line): Deleted.
+ (bmalloc::SmallAllocator::allocate): Deleted.
+ (bmalloc::SmallAllocator::objectCount): Deleted.
+ (bmalloc::SmallAllocator::derefCount): Deleted.
+ (bmalloc::SmallAllocator::refill): Deleted.
+ (bmalloc::SmallAllocator::clear): Deleted.
+
+2014-09-12 Geoffrey Garen <gg...@apple.com>
+
+ Fixed a goof in bmalloc Vector sizing
+ https://bugs.webkit.org/show_bug.cgi?id=136795
+
+ Reviewed by Gavin Barraclough and Sam Weinig.
+
+ We want our minimum vector to be page-sized since the OS will give us
+ a page no matter what -- but we want that many bytes, and not enough
+ bytes to store that many elements.
+
+ * bmalloc/Vector.h: Math is hard.
+
+2014-09-11 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc should segregate medium-sized objects by line like it does for small-sized objects
+ https://bugs.webkit.org/show_bug.cgi?id=136693
+
+ Reviewed by Gavin Barraclough.
+
+ 4% reduction in heap size on the MallocBench *_memory_warning benchmarks.
+
+ No throughput change.
+
+ We keep an array of medium allocators, just like our array of small
+ allocators.
+
+ In future, we can simplify the allocation fast path by merging the small
+ and medium allocator arrays. For now, this is the simplest change that
+ gets the win.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::Allocator):
+ (bmalloc::Allocator::scavenge):
+ (bmalloc::Allocator::allocateMedium):
+ * bmalloc/Allocator.h:
+ * bmalloc/Sizes.h:
+ (bmalloc::Sizes::mediumSizeClassFor):
+
+2014-09-11 Geoffrey Garen <gg...@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Renamed log => retire for clarity.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::scavenge):
+ (bmalloc::Allocator::retire):
+ (bmalloc::Allocator::allocateMedium):
+ (bmalloc::Allocator::allocateSlowCase):
+ (bmalloc::Allocator::log): Deleted.
+ * bmalloc/Allocator.h:
+
+2014-09-11 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: eager scavenge leaves behind a bogus allocator
+ https://bugs.webkit.org/show_bug.cgi?id=136743
+
+ Reviewed by Sam Weinig.
+
+ Be sure to clear the allocator after logging it in the eager scavenge
+ case, so that we don't later try to allocate out of the lines that we
+ have thrown away.
+
+ We didn't need to do this previously because scavenge would only happen
+ at thread exit time, after which no further allocation from the per-thread
+ cache would take place.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::scavenge):
+ * bmalloc/MediumAllocator.h:
+ (bmalloc::MediumAllocator::clear):
+ * bmalloc/SmallAllocator.h:
+ (bmalloc::SmallAllocator::clear):
+
+2014-09-05 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc should honor the FastMalloc statistics API
+ https://bugs.webkit.org/show_bug.cgi?id=136592
+
+ Reviewed by Gavin Barraclough.
+
+ We do this by tracking "size" and "capacity" in the VM heap.
+
+ The VM heap's "capacity" is all the VM we ever allocated.
+
+ The VM heap's "size" the subset of VM currently held onto by the
+ VM heap (and therefore not in use by the regular heap).
+
+ Somewhat ironically, reducing the process's memory footprint, increases
+ the size of the VM heap, since the VM heap holds the pages that are
+ purely virtual and not physical.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::size):
+ (bmalloc::Heap::capacity):
+ * bmalloc/Heap.h:
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::VMHeap):
+ (bmalloc::VMHeap::allocateSmallChunk):
+ (bmalloc::VMHeap::allocateMediumChunk):
+ (bmalloc::VMHeap::allocateLargeChunk):
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::size):
+ (bmalloc::VMHeap::capacity):
+ (bmalloc::VMHeap::allocateSmallPage):
+ (bmalloc::VMHeap::allocateMediumPage):
+ (bmalloc::VMHeap::allocateLargeRange):
+ (bmalloc::VMHeap::deallocateSmallPage):
+ (bmalloc::VMHeap::deallocateMediumPage):
+ (bmalloc::VMHeap::deallocateLargeRange):
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::heapSize):
+ (bmalloc::api::heapCapacity):
+
+2014-09-02 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc crashes on the EWS bots (due to bad large object allocation)
+ https://bugs.webkit.org/show_bug.cgi?id=136469
+
+ Reviewed by Andreas Kling.
+
+ It's possible to convince bmalloc to perform a bad large object allocation,
+ through these steps:
+
+ (1) Insert object A into freelist F0.
+
+ (2) Split, merge and split again A's neighbors such that object B is
+ inserted into freelist F0, with boundary tag and size equal to object A,
+ but pointer not completely equal to object A. Put object B at the head of F0.
+
+ (3) Allocate some other object from F0, swapping its position in the
+ freelist with object B, such that object A is now ahead of object B.
+
+ --> Now, the next allocation for size A/B will allocate object A, which
+ has a slightly wrong idea about where the object actually begins.
+ Immediately, you'll corrupt a little memory, and over time, you'll also
+ corrupt boundary tag metadata.
+
+ The solution is to store the begin pointer in the boundary tag. Luckily,
+ this doesn't make the tag any bigger, and it's not a noticeable slowdown
+ on MallocBench.
+
+ * bmalloc/Algorithm.h:
+ (bmalloc::rightShift):
+ * bmalloc/BeginTag.h:
+ (bmalloc::BeginTag::isInFreeList): This is the bug fix. Make sure to
+ validate the start pointer when popping off the free list. Through a
+ very uncommon set of steps, it is possible to have an item in the free
+ list that is valid by all accounts except for its start pointer.
+
+ * bmalloc/BoundaryTag.h:
+ (bmalloc::BoundaryTag::compactBegin):
+ (bmalloc::BoundaryTag::setRange):
+ (bmalloc::BoundaryTag::setSize): Deleted. Record a compact version of the
+ start pointer. We don't need the whole pointer -- just the offset, in
+ largeAlignment increments, into the relevant boundary tag bucket.
+
+ * bmalloc/BoundaryTagInlines.h:
+ (bmalloc::validateNext):
+ (bmalloc::BoundaryTag::init):
+ (bmalloc::BoundaryTag::mergeLarge):
+ (bmalloc::BoundaryTag::splitLarge):
+ * bmalloc/SegregatedFreeList.cpp:
+ (bmalloc::SegregatedFreeList::insert):
+ (bmalloc::SegregatedFreeList::takeGreedy):
+ (bmalloc::SegregatedFreeList::take): Provide the whole range instead of
+ the size when establishing a boundary tag, as required by the new
+ interface.
+
+ * bmalloc/Sizes.h:
+
+2014-08-14 Geoffrey Garen <gg...@apple.com>
+
+ Fixed a bmalloc crash seen on the EWS bot
+ https://bugs.webkit.org/show_bug.cgi?id=135955
+
+ Reviewed by Andreas Kling.
+
+ * bmalloc/Syscall.h: Some CG APIs vm_copy their input buffers. If the
+ input buffer is a malloc region, that region will get marked Copy-On-Write
+ by the kernel. Calls to madvise() for COW regions fail and return EINVAL
+ on older OS X's. In 10.10, they still fail, but they do not return
+ EINVAL.
+
+ So, we can only ASSERT that our syscalls succeed starting with 10.10.
+
+2014-08-14 Geoffrey Garen <gg...@apple.com>
+
+ Fixed the bmalloc build
+ https://bugs.webkit.org/show_bug.cgi?id=135953
+
+ Reviewed by Andreas Kling.
+
+ * bmalloc.xcodeproj/project.pbxproj: Marked a few headers as private.
+ These headers are used, so they must be available outside the project.
+
+2014-08-13 Daniel Bates <da...@apple.com>
+
+ Attempt to fix the build following <http://trac.webkit.org/changeset/172576>
+ (https://bugs.webkit.org/show_bug.cgi?id=135895)
+
+ Substitute PerThreadStorage<T>::initSharedKeyIfNeeded() for initSharedKeyIfNeeded() in
+ implementation of PerThread<T>::getFastCase().
+
+ * bmalloc/PerThread.h:
+ (bmalloc::PerThread<T>::getFastCase):
+
+2014-08-13 Daniel Bates <da...@apple.com>
+
+ Make bmalloc::PerThread work without C++ thread local storage
+ https://bugs.webkit.org/show_bug.cgi?id=135895
+
+ Reviewed by Geoffrey Garen.
+
+ Implement support for building bmalloc without C++ thread local storage.
+
+ * bmalloc/BPlatform.h: Remove macro define BPLATFORM_IOS_SIMULATOR. Added macro function
+ BCOMPILER_SUPPORTS() and macro define BCOMPILER_SUPPORTS_CXX_THREAD_LOCAL that can be used
+ to determine whether the compiler supports C++ thread local storage.
+ * bmalloc/PerThread.h:
+ (bmalloc::PerThreadStorage::get): Modified to call pthread_getspecific() when building
+ without C++ thread local storage.
+ (bmalloc::PerThreadStorage::initSharedKeyIfNeeded): Added.
+ (bmalloc::PerThreadStorage::init): Moved logic to initialize shared Pthread key from here to
+ PerThreadStorage::initSharedKeyIfNeeded().
+ (bmalloc::PerThread<T>::getFastCase): Modified to call PerThreadStorage::initSharedKeyIfNeeded()
+ before querying PerThreadStorage::get() when building without C++ thread local storage so as to
+ ensure that the shared key has been initialized.
+ (_pthread_setspecific_direct): Deleted.
+ (_pthread_getspecific_direct): Deleted.
+
+2014-08-13 Daniel Bates <da...@apple.com>
+
+ [iOS] Make JavaScriptCore and bmalloc build with the public SDK
+ https://bugs.webkit.org/show_bug.cgi?id=135848
+
+ Reviewed by Geoffrey Garen.
+
+ * bmalloc/BPlatform.h: Added macro BPLATFORM_IOS_SIMULATOR, which evaluates to true
+ when building for the iOS Simulator.
+ * bmalloc/PerThread.h: Use pthread_machdep.h code path when building for iOS Simulator
+ using the public SDK.
+ (_pthread_setspecific_direct): Added; only defined when building for the iOS Simulator
+ using the public SDK.
+ (_pthread_getspecific_direct): Added; only defined when building for the iOS Simulator
+ using the public SDK.
+
+2014-08-12 Daniel Bates <da...@apple.com>
+
+ BPLATFORM(IOS) always evaluates to false
+ https://bugs.webkit.org/show_bug.cgi?id=135843
+
+ Reviewed by Geoffrey Garen.
+
+ Fix typo in definition of BPLATFORM() and include system header TargetConditionals.h
+ (when building on an Apple platform) so that BPLATFORM(X) evaluates to true when
+ building for platform X. In particular, so that BPLATFORM(IOS) evaluates to true when
+ building for iOS.
+
+ As a side effect of this change, the change made in <http://trac.webkit.org/changeset/167289>
+ will be honored and iOS will assume a VM page size of 16kB (again) instead of 4kB.
+
+ * bmalloc/BPlatform.h:
+
+2014-08-11 Andy Estes <ae...@apple.com>
+
+ [iOS] Get rid of iOS.xcconfig
+ https://bugs.webkit.org/show_bug.cgi?id=135809
+
+ Reviewed by Joseph Pecoraro.
+
+ All iOS.xcconfig did was include AspenFamily.xcconfig, so there's no need for the indirection.
+
+ * Configurations/Base.xcconfig:
+ * Configurations/iOS.xcconfig: Removed.
+ * bmalloc.xcodeproj/project.pbxproj:
+
+2014-05-01 Dan Bernstein <mi...@apple.com>
+
+ Fixed production builds for the iOS Simulator.
+ <rdar://problem/16792221>
+
+ * Configurations/bmalloc.xcconfig: Include INSTALL_PATH_PREFIX in
+ PRIVATE_HEADERS_FOLDER_PATH when installing.
+
+2014-04-20 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Segregate pages by objects size
+ https://bugs.webkit.org/show_bug.cgi?id=131909
+
+ Reviewed by Andreas Kling.
+
+ 2% reduction in memory-at-end on the Membuster memory_warning benchmarks.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::allocateSlowCase):
+ * bmalloc/Allocator.h:
+ (bmalloc::Allocator::allocateFastCase):
+ (bmalloc::Allocator::smallAllocatorFor): Use the new shared helper
+ function for size class calculation.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::Deallocator):
+ (bmalloc::Deallocator::scavenge):
+ (bmalloc::Deallocator::deallocateSmallLine):
+ (bmalloc::Deallocator::allocateSmallLine):
+ * bmalloc/Deallocator.h: Keep a cache for every size class, since the
+ cache can't be shared anymore.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateSmallLineSlowCase):
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::deallocateSmallLine): Ditto.
+
+ (bmalloc::Heap::allocateSmallLine): Check size class in addition to
+ page refcount when allocating a line because we might have deallocated
+ the page and the recycled it for another size class.
+
+ (bmalloc::Heap::deallocateMediumLine):
+ (bmalloc::Heap::allocateMediumLine):
+ * bmalloc/Line.h:
+ (bmalloc::Line::refCount):
+ * bmalloc/Page.h:
+ (bmalloc::Page::refCount):
+ (bmalloc::Page::smallSizeClass):
+ (bmalloc::Page::setSmallSizeClass):
+ (bmalloc::Page<Traits>::refCount): Deleted.
+ * bmalloc/Sizes.h:
+ (bmalloc::Sizes::smallSizeClassFor): New shared API for computing
+ an index into an array from a size.
+
+2014-04-19 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Improved alignment in LargeChunk
+ https://bugs.webkit.org/show_bug.cgi?id=131895
+
+ Reviewed by Andreas Kling.
+
+ * bmalloc/Chunk.h:
+ * bmalloc/LargeChunk.h: Align to vmPageSize just like Chunk does.
+ Technically, the previous alignment was harmless, but I would prefer,
+ dear reader, not to have to explain the interlocking set of
+ circumstances that made it so.
+
+2014-04-19 Geoffrey Garen <gg...@apple.com>
+
+ Rolled out r167502 because it caused a crash on the facebook benchmark.
+
+ Unreviewed.
+
+ bmalloc: Added an XSmall line size
+ https://bugs.webkit.org/show_bug.cgi?id=131851
+
+ Reviewed by Sam Weinig.
+
+2014-04-19 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Mutex should be harder to use wrong
+ https://bugs.webkit.org/show_bug.cgi?id=131879
+
+ Reviewed by Andreas Kling.
+
+ Mutex now has a proper constructor, so you can't deadlock by forgetting
+ to initialize it.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::processXSmallAllocatorLog):
+ (bmalloc::Allocator::processSmallAllocatorLog):
+ (bmalloc::Allocator::processMediumAllocatorLog):
+ (bmalloc::Allocator::allocateLarge):
+ (bmalloc::Allocator::allocateXLarge): Global replace Mutex => StaticMutex,
+ since the Heap mutex is a static.
+
+ * bmalloc/AsyncTask.h:
+ (bmalloc::Function>::AsyncTask): Use Mutex, since we're not static. No
+ need for explicit initialization anymore.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::scavenge):
+ (bmalloc::Deallocator::deallocateLarge):
+ (bmalloc::Deallocator::deallocateXLarge):
+ (bmalloc::Deallocator::processObjectLog):
+ (bmalloc::Deallocator::deallocateSmallLine):
+ (bmalloc::Deallocator::deallocateXSmallLine):
+ (bmalloc::Deallocator::allocateSmallLine):
+ (bmalloc::Deallocator::allocateXSmallLine):
+ (bmalloc::Deallocator::deallocateMediumLine):
+ (bmalloc::Deallocator::allocateMediumLine):
+ * bmalloc/Deallocator.h:
+ * bmalloc/Heap.cpp:
+ (bmalloc::sleep):
+ (bmalloc::Heap::Heap):
+ (bmalloc::Heap::concurrentScavenge):
+ (bmalloc::Heap::scavenge):
+ (bmalloc::Heap::scavengeSmallPages):
+ (bmalloc::Heap::scavengeXSmallPages):
+ (bmalloc::Heap::scavengeMediumPages):
+ (bmalloc::Heap::scavengeLargeRanges):
+ (bmalloc::Heap::allocateXSmallLineSlowCase):
+ (bmalloc::Heap::allocateSmallLineSlowCase):
+ (bmalloc::Heap::allocateMediumLineSlowCase):
+ (bmalloc::Heap::allocateXLarge):
+ (bmalloc::Heap::deallocateXLarge):
+ (bmalloc::Heap::allocateLarge):
+ (bmalloc::Heap::deallocateLarge):
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::deallocateXSmallLine):
+ (bmalloc::Heap::allocateXSmallLine):
+ (bmalloc::Heap::deallocateSmallLine):
+ (bmalloc::Heap::allocateSmallLine):
+ (bmalloc::Heap::deallocateMediumLine):
+ (bmalloc::Heap::allocateMediumLine):
+ * bmalloc/Line.h:
+ (bmalloc::Line<Traits>::deref):
+ * bmalloc/Mutex.cpp: Removed.
+ * bmalloc/Mutex.h:
+ (bmalloc::Mutex::Mutex):
+ (bmalloc::Mutex::init): Deleted.
+ (bmalloc::Mutex::try_lock): Deleted.
+ (bmalloc::Mutex::lock): Deleted.
+ (bmalloc::Mutex::unlock): Deleted.
+ * bmalloc/Page.h:
+ (bmalloc::Page<Traits>::ref):
+ (bmalloc::Page<Traits>::deref):
+ (bmalloc::Page<Traits>::refCount):
+ * bmalloc/PerProcess.h:
+ (bmalloc::PerProcess::mutex):
+ (bmalloc::PerProcess<T>::getSlowCase):
+ * bmalloc/StaticMutex.cpp: Added.
+ (bmalloc::StaticMutex::lockSlowCase):
+ * bmalloc/StaticMutex.h: Added.
+ (bmalloc::StaticMutex::init):
+ (bmalloc::StaticMutex::try_lock):
+ (bmalloc::StaticMutex::lock):
+ (bmalloc::StaticMutex::unlock):
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::deallocateXSmallPage):
+ (bmalloc::VMHeap::deallocateSmallPage):
+ (bmalloc::VMHeap::deallocateMediumPage):
+ (bmalloc::VMHeap::deallocateLargeRange):
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::scavenge): Global replace Mutex => StaticMutex,
+ since the Heap mutex is a static.
+
+2014-04-18 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: AsyncTask should use Mutex instead of std::mutex
+ https://bugs.webkit.org/show_bug.cgi?id=131865
+
+ Reviewed by Gavin Barraclough.
+
+ std::mutex is so slow that it makes parallelizing simple tasks through
+ AsyncTask a net regression. Mutex fixes this.
+
+ * bmalloc/AsyncTask.h:
+ (bmalloc::Function>::AsyncTask):
+ (bmalloc::Function>::join):
+ (bmalloc::Function>::runSlowCase):
+ (bmalloc::Function>::entryPoint):
+ * bmalloc/Mutex.h:
+ (bmalloc::Mutex::init):
+
+2014-04-18 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Added an XSmall line size
+ https://bugs.webkit.org/show_bug.cgi?id=131851
+
+ Reviewed by Sam Weinig.
+
+ Reduces malloc footprint on Membuster recordings by 10%.
+
+ This is a throughput regression, but we're still way ahead of TCMalloc.
+ I have some ideas for how to recover the regression -- but I wanted to
+ get this win in first.
+
+ Full set of benchmark results:
+
+ bmalloc> ~/webkit/PerformanceTests/MallocBench/run-malloc-benchmarks --measure-heap nopatch:~/scratch/Build-nopatch/Release/ patch:~/webkit/WebKitBuild/Release/
+
+ nopatch patch Δ
+ Peak Memory:
+ reddit_memory_warning 7,896kB 7,532kB ^ 1.05x smaller
+ flickr_memory_warning 12,968kB 12,324kB ^ 1.05x smaller
+ theverge_memory_warning 16,672kB 15,200kB ^ 1.1x smaller
+
+ <geometric mean> 11,952kB 11,216kB ^ 1.07x smaller
+ <arithmetic mean> 12,512kB 11,685kB ^ 1.07x smaller
+ <harmonic mean> 11,375kB 10,726kB ^ 1.06x smaller
+
+ Memory at End:
+ reddit_memory_warning 7,320kB 6,856kB ^ 1.07x smaller
+ flickr_memory_warning 10,848kB 9,692kB ^ 1.12x smaller
+ theverge_memory_warning 16,380kB 14,872kB ^ 1.1x smaller
+
+ <geometric mean> 10,916kB 9,961kB ^ 1.1x smaller
+ <arithmetic mean> 11,516kB 10,473kB ^ 1.1x smaller
+ <harmonic mean> 10,350kB 9,485kB ^ 1.09x smaller
+
+ MallocBench> ~/webkit/PerformanceTests/MallocBench/run-malloc-benchmarks nopatch:~/scratch/Build-nopatch/Release/ patch:~/webkit/WebKitBuild/Release/
+
+ nopatch patch Δ
+ Execution Time:
+ churn 127ms 151ms ! 1.19x slower
+ list_allocate 130ms 164ms ! 1.26x slower
+ tree_allocate 109ms 127ms ! 1.17x slower
+ tree_churn 115ms 120ms ! 1.04x slower
+ facebook 240ms 259ms ! 1.08x slower
+ fragment 91ms 131ms ! 1.44x slower
+ fragment_iterate 105ms 106ms ! 1.01x slower
+ message_one 260ms 259ms ^ 1.0x faster
+ message_many 149ms 154ms ! 1.03x slower
+ medium 194ms 248ms ! 1.28x slower
+ big 157ms 160ms ! 1.02x slower
+
+ <geometric mean> 144ms 163ms ! 1.13x slower
+ <arithmetic mean> 152ms 171ms ! 1.12x slower
+ <harmonic mean> 137ms 156ms ! 1.14x slower
+
+ MallocBench> ~/webkit/PerformanceTests/MallocBench/run-malloc-benchmarks nopatch:~/scratch/Build-nopatch/Release/ patch:~/webkit/WebKitBuild/Release/
+
+ nopatch patch Δ
+ Execution Time:
+ churn 126ms 148ms ! 1.17x slower
+ churn --parallel 62ms 76ms ! 1.23x slower
+ list_allocate 130ms 164ms ! 1.26x slower
+ list_allocate --parallel 120ms 175ms ! 1.46x slower
+ tree_allocate 111ms 127ms ! 1.14x slower
+ tree_allocate --parallel 95ms 135ms ! 1.42x slower
+ tree_churn 115ms 124ms ! 1.08x slower
+ tree_churn --parallel 107ms 126ms ! 1.18x slower
+ facebook 240ms 276ms ! 1.15x slower
+ facebook --parallel 802ms 1,088ms ! 1.36x slower
+ fragment 92ms 130ms ! 1.41x slower
+ fragment --parallel 66ms 124ms ! 1.88x slower
+ fragment_iterate 109ms 127ms ! 1.17x slower
+ fragment_iterate --parallel 55ms 64ms ! 1.16x slower
+ message_one 260ms 260ms
+ message_many 170ms 238ms ! 1.4x slower
+ medium 185ms 250ms ! 1.35x slower
+ medium --parallel 210ms 334ms ! 1.59x slower
+ big 150ms 169ms ! 1.13x slower
+ big --parallel 138ms 144ms ! 1.04x slower
+
+ <geometric mean> 135ms 170ms ! 1.26x slower
+ <arithmetic mean> 167ms 214ms ! 1.28x slower
+ <harmonic mean> 117ms 148ms ! 1.26x slower
+
+ MallocBench> ~/webkit/PerformanceTests/MallocBench/run-malloc-benchmarks TC:~/scratch/Build-TCMalloc/Release/ patch:~/webkit/WebKitBuild/Release/
+
+ TC patch Δ
+ Peak Memory:
+ reddit_memory_warning 13,836kB 13,436kB ^ 1.03x smaller
+ flickr_memory_warning 24,868kB 25,188kB ! 1.01x bigger
+ theverge_memory_warning 24,504kB 26,636kB ! 1.09x bigger
+
+ <geometric mean> 20,353kB 20,812kB ! 1.02x bigger
+ <arithmetic mean> 21,069kB 21,753kB ! 1.03x bigger
+ <harmonic mean> 19,570kB 19,780kB ! 1.01x bigger
+
+ Memory at End:
+ reddit_memory_warning 8,656kB 10,016kB ! 1.16x bigger
+ flickr_memory_warning 11,844kB 13,784kB ! 1.16x bigger
+ theverge_memory_warning 18,516kB 22,748kB ! 1.23x bigger
+
+ <geometric mean> 12,382kB 14,644kB ! 1.18x bigger
+ <arithmetic mean> 13,005kB 15,516kB ! 1.19x bigger
+ <harmonic mean> 11,813kB 13,867kB ! 1.17x bigger
+
+ MallocBench> ~/webkit/PerformanceTests/MallocBench/run-malloc-benchmarks TC:~/scratch/Build-TCMalloc/Release/ patch:~/webkit/WebKitBuild/Release/
+
+ TC patch Δ
+ Execution Time:
+ churn 416ms 148ms ^ 2.81x faster
+ list_allocate 463ms 164ms ^ 2.82x faster
+ tree_allocate 292ms 127ms ^ 2.3x faster
+ tree_churn 157ms 120ms ^ 1.31x faster
+ facebook 327ms 276ms ^ 1.18x faster
+ fragment 335ms 129ms ^ 2.6x faster
+ fragment_iterate 344ms 108ms ^ 3.19x faster
+ message_one 386ms 258ms ^ 1.5x faster
+ message_many 410ms 154ms ^ 2.66x faster
+ medium 391ms 245ms ^ 1.6x faster
+ big 261ms 167ms ^ 1.56x faster
+
+ <geometric mean> 332ms 164ms ^ 2.02x faster
+ <arithmetic mean> 344ms 172ms ^ 1.99x faster
+ <harmonic mean> 317ms 157ms ^ 2.02x faster
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::Allocator): Don't assume that each allocator's
+ index corresponds with its size. Instead, use the size selection function
+ explicitly. Now that we have XSmall, some small allocator entries are
+ unused.
+
+ (bmalloc::Allocator::scavenge):
+ (bmalloc::Allocator::log):
+ (bmalloc::Allocator::processXSmallAllocatorLog):
+ (bmalloc::Allocator::allocateSlowCase):
+ * bmalloc/Allocator.h:
+ (bmalloc::Allocator::xSmallAllocatorFor):
+ (bmalloc::Allocator::allocateFastCase):
+ * bmalloc/Chunk.h:
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::scavenge):
+ (bmalloc::Deallocator::processObjectLog):
+ (bmalloc::Deallocator::deallocateSlowCase):
+ (bmalloc::Deallocator::deallocateXSmallLine):
+ (bmalloc::Deallocator::allocateXSmallLine):
+ * bmalloc/Deallocator.h:
+ (bmalloc::Deallocator::deallocateFastCase):
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::scavenge):
+ (bmalloc::Heap::scavengeXSmallPages):
+ (bmalloc::Heap::allocateXSmallLineSlowCase):
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::deallocateXSmallLine):
+ (bmalloc::Heap::allocateXSmallLine):
+ * bmalloc/LargeChunk.h:
+ (bmalloc::LargeChunk::get):
+ (bmalloc::LargeChunk::endTag):
+ * bmalloc/Line.h:
+ * bmalloc/MediumAllocator.h:
+ (bmalloc::MediumAllocator::allocate):
+ (bmalloc::MediumAllocator::refill):
+ * bmalloc/ObjectType.cpp:
+ (bmalloc::objectType):
+ * bmalloc/ObjectType.h:
+ (bmalloc::isXSmall):
+ (bmalloc::isSmall):
+ (bmalloc::isMedium):
+ (bmalloc::isLarge):
+ (bmalloc::isSmallOrMedium): Deleted.
+ * bmalloc/SegregatedFreeList.h: I boiler-plate copied existing code for
+ handling small objects. There's probably a reasonable way to share this
+ code in the future -- I'll look into that once it's stopped changing.
+
+ * bmalloc/Sizes.h: Tweaked size classes to make Membuster happy. This
+ is the main reason things got slower.
+
+ * bmalloc/SmallAllocator.h:
+ (bmalloc::SmallAllocator::allocate):
+ * bmalloc/SmallTraits.h:
+ * bmalloc/VMHeap.cpp:
+ (bmalloc::VMHeap::allocateXSmallChunk):
+ * bmalloc/VMHeap.h:
+ (bmalloc::VMHeap::allocateXSmallPage):
+ (bmalloc::VMHeap::deallocateXSmallPage):
+ * bmalloc/XSmallAllocator.h: Added.
+ (bmalloc::XSmallAllocator::isNull):
+ (bmalloc::XSmallAllocator::canAllocate):
+ (bmalloc::XSmallAllocator::XSmallAllocator):
+ (bmalloc::XSmallAllocator::line):
+ (bmalloc::XSmallAllocator::allocate):
+ (bmalloc::XSmallAllocator::objectCount):
+ (bmalloc::XSmallAllocator::derefCount):
+ (bmalloc::XSmallAllocator::refill):
+ * bmalloc/XSmallChunk.h: Added.
+ * bmalloc/XSmallLine.h: Added.
+ * bmalloc/XSmallPage.h: Added.
+ * bmalloc/XSmallTraits.h: Added.
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::realloc): Boiler-plate copy, as above.
+
+2014-04-14 Geoffrey Garen <gg...@apple.com>
+
+ MallocBench should scavenge explicitly instead of waiting
+ https://bugs.webkit.org/show_bug.cgi?id=131661
+
+ Reviewed by Andreas Kling.
+
+ Added explicit scavenge support to bmalloc. This isn't a memory win,
+ since bmalloc's per-thread cache is so small. But it makes testing
+ simpler.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::~Allocator):
+ (bmalloc::Allocator::scavenge):
+ * bmalloc/Allocator.h:
+ * bmalloc/Cache.cpp:
+ (bmalloc::Cache::operator new):
+ (bmalloc::Cache::operator delete):
+ (bmalloc::Cache::Cache):
+ (bmalloc::Cache::scavenge):
+ * bmalloc/Cache.h:
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::~Deallocator):
+ (bmalloc::Deallocator::scavenge):
+ * bmalloc/Deallocator.h: Factored existing scavenging code into helper
+ functions, for reuse.
+
+ * bmalloc/Heap.cpp:
+ (bmalloc::sleep):
+ (bmalloc::Heap::concurrentScavenge):
+ (bmalloc::Heap::scavenge):
+ (bmalloc::Heap::scavengeSmallPages):
+ (bmalloc::Heap::scavengeMediumPages):
+ (bmalloc::Heap::scavengeLargeRanges):
+ * bmalloc/Heap.h: Made scavenge sleep duration a parameter. Forced
+ scavenging -- in response to a benchmark or a low memory warning --
+ wants to complete as soon as possible, so its sleep duration is 0.
+
+ * bmalloc/bmalloc.h:
+ (bmalloc::api::scavenge):
+ * bmalloc/mbmalloc.cpp: Exported the scavenge API for MallocBench's use.
+
+2014-04-14 Geoffrey Garen <gg...@apple.com>
+
+ Use 4kB pages on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=131658
+
+ Reviewed by Sam Weinig.
+
+ This reduces memory use a lot on Membuster:
+
+ base patch Δ
+ Execution Time:
+ reddit_memory_warning 18ms 17ms ^ 1.06x faster
+ flickr_memory_warning 34ms 36ms ! 1.06x slower
+ theverge_memory_warning 39ms 41ms ! 1.05x slower
+
+ <geometric mean> 29ms 29ms ! 1.02x slower
+ <arithmetic mean> 30ms 31ms ! 1.03x slower
+ <harmonic mean> 27ms 27ms ^ 1.0x faster
+
+ Peak Memory:
+ reddit_memory_warning 16,412kB 16,436kB ! 1.0x bigger
+ flickr_memory_warning 30,120kB 30,184kB ! 1.0x bigger
+ theverge_memory_warning 33,408kB 33,420kB ! 1.0x bigger
+
+ <geometric mean> 25,466kB 25,499kB ! 1.0x bigger
+ <arithmetic mean> 26,647kB 26,680kB ! 1.0x bigger
+ <harmonic mean> 24,181kB 24,214kB ! 1.0x bigger
+
+ Memory at End:
+ reddit_memory_warning 2,404kB 1,920kB ^ 1.25x smaller
+ flickr_memory_warning 3,764kB 3,072kB ^ 1.23x smaller
+ theverge_memory_warning 3,648kB 3,132kB ^ 1.16x smaller
+
+ <geometric mean> 3,208kB 2,644kB ^ 1.21x smaller
+ <arithmetic mean> 3,272kB 2,708kB ^ 1.21x smaller
+ <harmonic mean> 3,139kB 2,574kB ^ 1.22x smaller
+
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/BPlatform.h: Added.
+ * bmalloc/VMAllocate.h: Only use 16kB pages on iOS because the page size
+ is 4kB on Mac.
+
+2014-04-14 Alexey Proskuryakov <ap...@apple.com>
+
+ Fixed svn:ignore on bmalloc.xcodeproj, it had erroneous leading spaces.
+
+ * bmalloc.xcodeproj: Modified property svn:ignore.
+
+2014-04-13 Geoffrey Garen <gg...@apple.com>
+
+ Fixed some mbmalloc exports
+ https://bugs.webkit.org/show_bug.cgi?id=131599
+
+ Reviewed by Ryosuke Niwa.
+
+ * bmalloc.xcodeproj/project.pbxproj: Made some headers a private part
+ of the project, so we can call them from API.
+
+ * bmalloc/mbmalloc.cpp: Marked the mbmalloc functions with default
+ visibility, so they show up as exported in the .dylib.
+
+2014-04-09 Geoffrey Garen <gg...@apple.com>
+
+ Put bmalloc headers in the right place
+ https://bugs.webkit.org/show_bug.cgi?id=131464
+
+ Reviewed by Mark Rowe.
+
+ * Configurations/bmalloc.xcconfig: Set PRIVATE_HEADERS_FOLDER_PATH to
+ specify that we don't just want to dump all of our generically-named
+ headers into /usr/local/include.
+
+2014-04-08 Geoffrey Garen <gg...@apple.com>
+
+ Made bmalloc more #include friendly
+ https://bugs.webkit.org/show_bug.cgi?id=131386
+
+ Reviewed by Andreas Kling.
+
+ Marked a bunch of headers private so they can be used from client code
+ that #includes bmalloc.h.
+
+ Renamed ASSERT macros to BASSERT. This matches their header, which already
+ had to be renamed, and fixes conflicts with WTF's ASSERT macros.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::allocateSlowCase):
+ * bmalloc/AsyncTask.h:
+ (bmalloc::Function>::runSlowCase):
+ * bmalloc/BAssert.h:
+ * bmalloc/BoundaryTag.h:
+ (bmalloc::BoundaryTag::setSize):
+ * bmalloc/BoundaryTagInlines.h:
+ (bmalloc::validate):
+ (bmalloc::BoundaryTag::init):
+ (bmalloc::BoundaryTag::deallocate):
+ (bmalloc::BoundaryTag::splitLarge):
+ (bmalloc::BoundaryTag::allocate):
+ * bmalloc/Chunk.h:
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::processObjectLog):
+ (bmalloc::Deallocator::deallocateSlowCase):
+ * bmalloc/Deallocator.h:
+ (bmalloc::Deallocator::deallocateFastCase):
+ * bmalloc/FixedVector.h:
+ (bmalloc::Capacity>::operator):
+ (bmalloc::Capacity>::push):
+ (bmalloc::Capacity>::pop):
+ (bmalloc::Capacity>::shrink):
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::allocateLarge):
+ * bmalloc/LargeChunk.h:
+ (bmalloc::LargeChunk::get):
+ (bmalloc::LargeChunk::endTag):
+ * bmalloc/Line.h:
+ (bmalloc::Line<Traits>::concurrentRef):
+ (bmalloc::Line<Traits>::deref):
+ * bmalloc/MediumAllocator.h:
+ (bmalloc::MediumAllocator::allocate):
+ * bmalloc/ObjectType.h:
+ (bmalloc::isSmall):
+ * bmalloc/Page.h:
+ (bmalloc::Page<Traits>::ref):
+ (bmalloc::Page<Traits>::deref):
+ * bmalloc/PerThread.h:
+ (bmalloc::PerThread<T>::getSlowCase):
+ * bmalloc/SegregatedFreeList.cpp:
+ (bmalloc::SegregatedFreeList::SegregatedFreeList):
+ (bmalloc::SegregatedFreeList::insert):
+ * bmalloc/SmallAllocator.h:
+ (bmalloc::SmallAllocator::allocate):
+ (bmalloc::SmallAllocator::refill):
+ * bmalloc/Syscall.h:
+ * bmalloc/VMAllocate.h:
+ (bmalloc::vmValidate):
+ (bmalloc::vmAllocate):
+ (bmalloc::vmDeallocatePhysicalPagesSloppy):
+ * bmalloc/Vector.h:
+ (bmalloc::Vector<T>::operator):
+ (bmalloc::Vector<T>::pop):
+ (bmalloc::Vector<T>::shrink):
+ * bmalloc/XLargeChunk.h:
+ (bmalloc::XLargeChunk::range):
+ (bmalloc::XLargeChunk::size):
+
+2014-04-08 Geoffrey Garen <gg...@apple.com>
+
+ Removed an unused file.
+
+ Unreviewed.
+
+ * bmalloc/AsyncTask.cpp: Removed.
+
+2014-04-07 Geoffrey Garen <gg...@apple.com>
+
+ Build bmalloc on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=131333
+
+ Reviewed by Mark Rowe.
+
+ * Makefile: Added. For make clients.
+
+ These files are required for building any project in WebKit. I copied
+ them from WTF:
+ * Configurations: Added.
+ * Configurations/Base.xcconfig: Added.
+ * Configurations/DebugRelease.xcconfig: Added.
+ * Configurations/bmalloc.xcconfig: Added.
+ * Configurations/iOS.xcconfig: Added.
+ * Configurations/mbmalloc.xcconfig: Added.
+
+ * bmalloc.xcodeproj/project.pbxproj: I removed per-project-file stuff
+ from here because everything is in .xcconfig files now.
+
+ I had to fix a bunch of minor warnings, since they're enabled in our
+ .xcconfig files:
+
+ * bmalloc/AsyncTask.h:
+ (bmalloc::Function>::AsyncTask):
+ * bmalloc/BAssert.h:
+ * bmalloc/BoundaryTagInlines.h:
+ (bmalloc::validate):
+ * bmalloc/Heap.cpp:
+ (bmalloc::Heap::Heap):
+ (bmalloc::Heap::allocateLarge):
+ (bmalloc::Heap::deallocateLarge):
+ * bmalloc/Mutex.h:
+ (bmalloc::Mutex::Mutex): Deleted.
+ * bmalloc/VMAllocate.h:
+ (bmalloc::vmValidate):
+ * bmalloc/mbmalloc.cpp:
+
+2014-04-07 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: Fixed a leak in the per-thread cache
+ https://bugs.webkit.org/show_bug.cgi?id=131330
+
+ Reviewed by Andreas Kling.
+
+ Remember to deallocate our line caches upon thread exit.
+
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::~Deallocator):
+
+2014-04-07 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc: rolled out the tryLock experiment
+ https://bugs.webkit.org/show_bug.cgi?id=131328
+
+ Reviewed by Andreas Kling.
+
+ It wasn't a speedup.
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::processSmallAllocatorLog):
+ (bmalloc::Allocator::processMediumAllocatorLog):
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::processObjectLog):
+ (bmalloc::Deallocator::deallocateSlowCase):
+ (bmalloc::Deallocator::deallocateSmallLine):
+ (bmalloc::Deallocator::deallocateMediumLine):
+ * bmalloc/Deallocator.h:
+ (bmalloc::Deallocator::deallocateFastCase):
+ * bmalloc/Heap.h:
+ (bmalloc::Heap::deallocateSmallLine):
+ (bmalloc::Heap::deallocateMediumLine):
+ * bmalloc/Line.h:
+ (bmalloc::Line<Traits>::deref):
+ * bmalloc/Page.h:
+ (bmalloc::Page<Traits>::deref):
+
+2014-04-07 Geoffrey Garen <gg...@apple.com>
+
+ bmalloc
+ https://bugs.webkit.org/show_bug.cgi?id=131170
+
+ Reviewed by Andreas Kling.
+
+ Initial commit.
+
+ * bmalloc: Added.
+ * bmalloc.xcodeproj: Added.
+ * bmalloc.xcodeproj/project.pbxproj: Added.
+ * bmalloc/Algorithm.h: Added.
+ (bmalloc::max):
+ (bmalloc::min):
+ (bmalloc::mask):
+ (bmalloc::test):
+ (bmalloc::roundUpToMultipleOf):
+ (bmalloc::roundDownToMultipleOf):
+ (bmalloc::sizeOf):
+ (bmalloc::bitCount):
+ (bmalloc::isPowerOfTwo):
+ * bmalloc/Allocator.cpp: Added.
+ (bmalloc::Allocator::Allocator):
+ (bmalloc::Allocator::~Allocator):
+ (bmalloc::Allocator::log):
+ (bmalloc::Allocator::processSmallAllocatorLog):
+ (bmalloc::Allocator::processMediumAllocatorLog):
+ (bmalloc::Allocator::allocateLarge):
+ (bmalloc::Allocator::allocateXLarge):
+ (bmalloc::Allocator::allocateMedium):
+ (bmalloc::Allocator::allocateSlowCase):
+ * bmalloc/Allocator.h: Added.
+ (bmalloc::Allocator::smallAllocatorFor):
+ (bmalloc::Allocator::allocateFastCase):
+ (bmalloc::Allocator::allocate):
+ * bmalloc/AsyncTask.cpp: Added.
+ (bmalloc::AsyncTask<Function>::runSlowCase):
+ (bmalloc::AsyncTask<Function>::pthreadEntryPoint):
+ (bmalloc::AsyncTask<Function>::entryPoint):
+ * bmalloc/AsyncTask.h: Added.
+ (bmalloc::Function>::AsyncTask):
+ (bmalloc::Function>::join):
+ (bmalloc::Function>::run):
+ (bmalloc::Function>::runSlowCase):
+ (bmalloc::Function>::pthreadEntryPoint):
+ (bmalloc::Function>::entryPoint):
+ * bmalloc/BAssert.h: Added.
+ * bmalloc/BeginTag.h: Added.
+ (bmalloc::BeginTag::isInFreeList):
+ * bmalloc/BoundaryTag.h: Added.
+ (bmalloc::BoundaryTag::isXLarge):
+ (bmalloc::BoundaryTag::setXLarge):
+ (bmalloc::BoundaryTag::isFree):
+ (bmalloc::BoundaryTag::setFree):
+ (bmalloc::BoundaryTag::isEnd):
+ (bmalloc::BoundaryTag::setEnd):
+ (bmalloc::BoundaryTag::hasPhysicalPages):
+ (bmalloc::BoundaryTag::setHasPhysicalPages):
+ (bmalloc::BoundaryTag::isNull):
+ (bmalloc::BoundaryTag::clear):
+ (bmalloc::BoundaryTag::size):
+ (bmalloc::BoundaryTag::setSize):
+ (bmalloc::BoundaryTag::prev):
+ (bmalloc::BoundaryTag::next):
+ * bmalloc/BoundaryTagInlines.h: Added.
+ (bmalloc::validate):
+ (bmalloc::validatePrev):
+ (bmalloc::validateNext):
+ (bmalloc::BoundaryTag::init):
+ (bmalloc::BoundaryTag::mergeLargeLeft):
+ (bmalloc::BoundaryTag::mergeLargeRight):
+ (bmalloc::BoundaryTag::mergeLarge):
+ (bmalloc::BoundaryTag::deallocate):
+ (bmalloc::BoundaryTag::splitLarge):
+ (bmalloc::BoundaryTag::allocate):
+ * bmalloc/Cache.cpp: Added.
+ (bmalloc::Cache::operator new):
+ (bmalloc::Cache::operator delete):
+ (bmalloc::Cache::Cache):
+ (bmalloc::Cache::allocateSlowCase):
+ (bmalloc::Cache::allocateSlowCaseNullCache):
+ (bmalloc::Cache::deallocateSlowCase):
+ (bmalloc::Cache::deallocateSlowCaseNullCache):
+ * bmalloc/Cache.h: Added.
+ (bmalloc::Cache::allocator):
+ (bmalloc::Cache::deallocator):
+ (bmalloc::Cache::allocateFastCase):
+ (bmalloc::Cache::deallocateFastCase):
+ (bmalloc::Cache::allocate):
+ (bmalloc::Cache::deallocate):
+ * bmalloc/Chunk.h: Added.
+ (bmalloc::Chunk::begin):
+ (bmalloc::Chunk::end):
+ (bmalloc::Chunk::lines):
+ (bmalloc::Chunk::pages):
+ * bmalloc/Deallocator.cpp: Added.
+ (bmalloc::Deallocator::Deallocator):
+ (bmalloc::Deallocator::~Deallocator):
+ (bmalloc::Deallocator::deallocateLarge):
+ (bmalloc::Deallocator::deallocateXLarge):
+ (bmalloc::Deallocator::processObjectLog):
+ (bmalloc::Deallocator::deallocateSlowCase):
+ (bmalloc::Deallocator::deallocateSmallLine):
+ (bmalloc::Deallocator::allocateSmallLine):
+ (bmalloc::Deallocator::deallocateMediumLine):
+ (bmalloc::Deallocator::allocateMediumLine):
+ * bmalloc/Deallocator.h: Added.
+ (bmalloc::Deallocator::deallocateFastCase):
+ (bmalloc::Deallocator::deallocate):
+ * bmalloc/EndTag.h: Added.
+ (bmalloc::EndTag::operator=):
+ * bmalloc/FixedVector.h: Added.
+ (bmalloc::FixedVector::begin):
+ (bmalloc::FixedVector::end):
+ (bmalloc::FixedVector::size):
+ (bmalloc::FixedVector::capacity):
+ (bmalloc::FixedVector::clear):
+ (bmalloc::FixedVector::isEmpty):
+ (bmalloc::Capacity>::FixedVector):
+ (bmalloc::Capacity>::operator):
+ (bmalloc::Capacity>::push):
+ (bmalloc::Capacity>::pop):
+ (bmalloc::Capacity>::shrink):
+ * bmalloc/Heap.cpp: Added.
+ (bmalloc::sleep):
+ (bmalloc::Heap::Heap):
+ (bmalloc::Heap::concurrentScavenge):
+ (bmalloc::Heap::scavengeSmallPages):
+ (bmalloc::Heap::scavengeMediumPages):
+ (bmalloc::Heap::scavengeLargeRanges):
+ (bmalloc::Heap::allocateSmallLineSlowCase):
+ (bmalloc::Heap::allocateMediumLineSlowCase):
+ (bmalloc::Heap::allocateXLarge):
+ (bmalloc::Heap::deallocateXLarge):
+ (bmalloc::Heap::allocateLarge):
+ (bmalloc::Heap::deallocateLarge):
+ * bmalloc/Heap.h: Added.
+ (bmalloc::Heap::deallocateSmallLine):
+ (bmalloc::Heap::allocateSmallLine):
+ (bmalloc::Heap::deallocateMediumLine):
+ (bmalloc::Heap::allocateMediumLine):
+ * bmalloc/Inline.h: Added.
+ * bmalloc/LargeChunk.h: Added.
+ (bmalloc::LargeChunk::begin):
+ (bmalloc::LargeChunk::end):
+ (bmalloc::LargeChunk::create):
+ (bmalloc::LargeChunk::get):
+ (bmalloc::LargeChunk::beginTag):
+ (bmalloc::LargeChunk::endTag):
+ * bmalloc/Line.h: Added.
+ (bmalloc::Line<Traits>::begin):
+ (bmalloc::Line<Traits>::end):
+ (bmalloc::Line<Traits>::concurrentRef):
+ (bmalloc::Line<Traits>::deref):
+ * bmalloc/MediumAllocator.h: Added.
+ (bmalloc::MediumAllocator::isNull):
+ (bmalloc::MediumAllocator::MediumAllocator):
+ (bmalloc::MediumAllocator::line):
+ (bmalloc::MediumAllocator::allocate):
+ (bmalloc::MediumAllocator::derefCount):
+ (bmalloc::MediumAllocator::refill):
+ * bmalloc/MediumChunk.h: Added.
+ * bmalloc/MediumLine.h: Added.
+ * bmalloc/MediumPage.h: Added.
+ * bmalloc/MediumTraits.h: Added.
+ * bmalloc/Mutex.cpp: Added.
+ (bmalloc::Mutex::lockSlowCase):
+ * bmalloc/Mutex.h: Added.
+ (bmalloc::Mutex::Mutex):
+ (bmalloc::Mutex::try_lock):
+ (bmalloc::Mutex::lock):
+ (bmalloc::Mutex::unlock):
+ * bmalloc/ObjectType.cpp: Added.
+ (bmalloc::objectType):
+ * bmalloc/ObjectType.h: Added.
+ (bmalloc::isSmallOrMedium):
+ (bmalloc::isSmall):
+ * bmalloc/Page.h: Added.
+ (bmalloc::Page<Traits>::ref):
+ (bmalloc::Page<Traits>::deref):
+ (bmalloc::Page<Traits>::refCount):
+ * bmalloc/PerProcess.h: Added.
+ (bmalloc::PerProcess::mutex):
+ (bmalloc::PerProcess<T>::getFastCase):
+ (bmalloc::PerProcess<T>::get):
+ (bmalloc::PerProcess<T>::getSlowCase):
+ * bmalloc/PerThread.h: Added.
+ (bmalloc::PerThreadStorage<Cache>::get):
+ (bmalloc::PerThreadStorage<Cache>::init):
+ (bmalloc::PerThreadStorage::get):
+ (bmalloc::PerThreadStorage::init):
+ (bmalloc::PerThread<T>::getFastCase):
+ (bmalloc::PerThread<T>::get):
+ (bmalloc::PerThread<T>::destructor):
+ (bmalloc::PerThread<T>::getSlowCase):
+ * bmalloc/Range.h: Added.
+ (bmalloc::Range::Range):
+ (bmalloc::Range::begin):
+ (bmalloc::Range::end):
+ (bmalloc::Range::size):
+ (bmalloc::Range::operator!):
+ (bmalloc::Range::operator<):
+ * bmalloc/SegregatedFreeList.cpp: Added.
+ (bmalloc::SegregatedFreeList::SegregatedFreeList):
+ (bmalloc::SegregatedFreeList::insert):
+ (bmalloc::SegregatedFreeList::takeGreedy):
+ (bmalloc::SegregatedFreeList::take):
+ * bmalloc/SegregatedFreeList.h: Added.
+ * bmalloc/Sizes.h: Added.
+ * bmalloc/SmallAllocator.h: Added.
+ (bmalloc::SmallAllocator::isNull):
+ (bmalloc::SmallAllocator::canAllocate):
+ (bmalloc::SmallAllocator::SmallAllocator):
+ (bmalloc::SmallAllocator::line):
+ (bmalloc::SmallAllocator::allocate):
+ (bmalloc::SmallAllocator::objectCount):
+ (bmalloc::SmallAllocator::derefCount):
+ (bmalloc::SmallAllocator::refill):
+ * bmalloc/SmallChunk.h: Added.
+ * bmalloc/SmallLine.h: Added.
+ * bmalloc/SmallPage.h: Added.
+ * bmalloc/SmallTraits.h: Added.
+ * bmalloc/Syscall.h: Added.
+ * bmalloc/VMAllocate.h: Added.
+ (bmalloc::vmSize):
+ (bmalloc::vmValidate):
+ (bmalloc::vmAllocate):
+ (bmalloc::vmDeallocate):
+ (bmalloc::vmDeallocatePhysicalPages):
+ (bmalloc::vmAllocatePhysicalPages):
+ (bmalloc::vmDeallocatePhysicalPagesSloppy):
+ (bmalloc::vmAllocatePhysicalPagesSloppy):
+ * bmalloc/VMHeap.cpp: Added.
+ (bmalloc::VMHeap::VMHeap):
+ (bmalloc::VMHeap::allocateSmallChunk):
+ (bmalloc::VMHeap::allocateMediumChunk):
+ (bmalloc::VMHeap::allocateLargeChunk):
+ * bmalloc/VMHeap.h: Added.
+ (bmalloc::VMHeap::allocateSmallPage):
+ (bmalloc::VMHeap::allocateMediumPage):
+ (bmalloc::VMHeap::allocateLargeRange):
+ (bmalloc::VMHeap::deallocateSmallPage):
+ (bmalloc::VMHeap::deallocateMediumPage):
+ (bmalloc::VMHeap::deallocateLargeRange):
+ * bmalloc/Vector.h: Added.
+ (bmalloc::Vector::begin):
+ (bmalloc::Vector::end):
+ (bmalloc::Vector::size):
+ (bmalloc::Vector::capacity):
+ (bmalloc::Vector::last):
+ (bmalloc::Vector::pop):
+ (bmalloc::Vector<T>::Vector):
+ (bmalloc::Vector<T>::~Vector):
+ (bmalloc::Vector<T>::operator):
+ (bmalloc::Vector<T>::push):
+ (bmalloc::Vector<T>::pop):
+ (bmalloc::Vector<T>::shrink):
+ (bmalloc::Vector<T>::reallocateBuffer):
+ (bmalloc::Vector<T>::shrinkCapacity):
+ (bmalloc::Vector<T>::growCapacity):
+ * bmalloc/XLargeChunk.h: Added.
+ (bmalloc::XLargeChunk::get):
+ (bmalloc::XLargeChunk::begin):
+ (bmalloc::XLargeChunk::XLargeChunk):
+ (bmalloc::XLargeChunk::create):
+ (bmalloc::XLargeChunk::destroy):
+ (bmalloc::XLargeChunk::range):
+ (bmalloc::XLargeChunk::size):
+ * bmalloc/bmalloc.h: Added.
+ (bmalloc::api::malloc):
+ (bmalloc::api::free):
+ (bmalloc::api::realloc):
+ * bmalloc/mbmalloc.cpp: Added.
+
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/Configurations/Base.xcconfig b/weex_core/Source/android/jsengine/dependence/bmalloc/Configurations/Base.xcconfig
new file mode 100644
index 0000000000..4b9bfd9654
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/Configurations/Base.xcconfig
@@ -0,0 +1,119 @@
+// Copyright (C) 2009-2017 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "../../../../Internal/Configurations/HaveInternalSDK.xcconfig"
+
+USE_INTERNAL_SDK = $(USE_INTERNAL_SDK_$(CONFIGURATION));
+USE_INTERNAL_SDK_Production = YES;
+USE_INTERNAL_SDK_Debug = $(HAVE_INTERNAL_SDK);
+USE_INTERNAL_SDK_Release = $(HAVE_INTERNAL_SDK);
+
+ALWAYS_SEARCH_USER_PATHS = NO;
+
+CLANG_CXX_LANGUAGE_STANDARD = gnu++14;
+CLANG_CXX_LIBRARY = libc++;
+CLANG_WARN_BOOL_CONVERSION = YES;
+CLANG_WARN_CONSTANT_CONVERSION = YES;
+CLANG_WARN_CXX0X_EXTENSIONS = NO;
+CLANG_WARN_EMPTY_BODY = YES;
+CLANG_WARN_ENUM_CONVERSION = YES;
+CLANG_WARN_INFINITE_RECURSION = YES;
+CLANG_WARN_INT_CONVERSION = YES;
+CLANG_WARN_SUSPICIOUS_MOVE = YES;
+CLANG_WARN_UNREACHABLE_CODE = YES;
+CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+DEBUG_INFORMATION_FORMAT = dwarf-with-dsym;
+GCC_C_LANGUAGE_STANDARD = gnu99;
+GCC_DEBUGGING_SYMBOLS = default;
+GCC_DYNAMIC_NO_PIC = NO;
+GCC_ENABLE_CPP_EXCEPTIONS = NO;
+GCC_ENABLE_CPP_RTTI = NO;
+GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+GCC_ENABLE_SYMBOL_SEPARATION = NO;
+GCC_FAST_OBJC_DISPATCH = YES;
+GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
+GCC_NO_COMMON_BLOCKS = YES;
+GCC_OBJC_CALL_CXX_CDTORS = YES;
+GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ENABLE_STRICT_OBJC_MSGSEND = YES;
+GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) $(inherited);
+GCC_STRICT_ALIASING = YES;
+GCC_THREADSAFE_STATICS = NO;
+GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+// FIXME: <http://webkit.org/b/107093> WTF should build with -Wshorten-64-to-32
+GCC_WARN_64_TO_32_BIT_CONVERSION = $(GCC_WARN_64_TO_32_BIT_CONVERSION_$(CURRENT_ARCH));
+GCC_WARN_64_TO_32_BIT_CONVERSION_ = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_armv7 = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_armv7k = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_armv7s = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_arm64 = NO;
+GCC_WARN_64_TO_32_BIT_CONVERSION_arm64e = NO;
+GCC_WARN_64_TO_32_BIT_CONVERSION_i386 = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_x86_64 = NO;
+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
+GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+GCC_WARN_ABOUT_RETURN_TYPE = YES;
+GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
+GCC_WARN_SIGN_COMPARE = YES;
+GCC_WARN_UNDECLARED_SELECTOR = YES;
+GCC_WARN_UNINITIALIZED_AUTOS = YES;
+GCC_WARN_UNUSED_FUNCTION = YES;
+GCC_WARN_UNUSED_VARIABLE = YES;
+PREBINDING = NO;
+WARNING_CFLAGS = -Wall -Wextra -Wcast-qual -Wchar-subscripts -Wextra-tokens -Wformat=2 -Winit-self -Wmissing-format-attribute -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wundef -Wwrite-strings -Wexit-time-destructors -Wglobal-constructors -Wtautological-compare -Wimplicit-fallthrough;
+
+TARGET_MAC_OS_X_VERSION_MAJOR = $(TARGET_MAC_OS_X_VERSION_MAJOR$(MACOSX_DEPLOYMENT_TARGET:suffix:identifier));
+TARGET_MAC_OS_X_VERSION_MAJOR_10 = 101000;
+TARGET_MAC_OS_X_VERSION_MAJOR_11 = 101100;
+TARGET_MAC_OS_X_VERSION_MAJOR_12 = 101200;
+TARGET_MAC_OS_X_VERSION_MAJOR_13 = 101300;
+TARGET_MAC_OS_X_VERSION_MAJOR_14 = 101400;
+
+SUPPORTED_PLATFORMS = iphoneos iphonesimulator macosx appletvos appletvsimulator watchos watchsimulator;
+
+// DEBUG_DEFINES, GCC_OPTIMIZATION_LEVEL, STRIP_INSTALLED_PRODUCT and DEAD_CODE_STRIPPING vary between the debug and normal variants.
+// We set up the values for each variant here, and have the Debug configuration in the Xcode project use the _debug variant.
+DEBUG_DEFINES_debug = ;
+DEBUG_DEFINES_normal = NDEBUG;
+DEBUG_DEFINES = $(DEBUG_DEFINES_$(CURRENT_VARIANT));
+
+GCC_OPTIMIZATION_LEVEL = $(GCC_OPTIMIZATION_LEVEL_$(CURRENT_VARIANT));
+GCC_OPTIMIZATION_LEVEL_normal = 3;
+GCC_OPTIMIZATION_LEVEL_debug = 0;
+
+STRIP_INSTALLED_PRODUCT = $(STRIP_INSTALLED_PRODUCT_$(CURRENT_VARIANT));
+STRIP_INSTALLED_PRODUCT_normal = YES;
+STRIP_INSTALLED_PRODUCT_debug = NO;
+
+DEAD_CODE_STRIPPING_debug = NO;
+DEAD_CODE_STRIPPING_normal = YES;
+DEAD_CODE_STRIPPING = $(DEAD_CODE_STRIPPING_$(CURRENT_VARIANT));
+
+SDKROOT = macosx.internal;
+
+OTHER_CFLAGS = $(ASAN_OTHER_CFLAGS);
+OTHER_CPLUSPLUSFLAGS = $(ASAN_OTHER_CPLUSPLUSFLAGS);
+OTHER_LDFLAGS = $(ASAN_OTHER_LDFLAGS);
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/Configurations/DebugRelease.xcconfig b/weex_core/Source/android/jsengine/dependence/bmalloc/Configurations/DebugRelease.xcconfig
new file mode 100644
index 0000000000..cdf3f713d3
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/Configurations/DebugRelease.xcconfig
@@ -0,0 +1,43 @@
+// Copyright (C) 2009, 2010, 2013 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "Base.xcconfig"
+
+ARCHS = $(ARCHS_STANDARD_32_64_BIT);
+ONLY_ACTIVE_ARCH = YES;
+
+TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR);
+
+MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(PLATFORM_NAME)_$(TARGET_MAC_OS_X_VERSION_MAJOR));
+MACOSX_DEPLOYMENT_TARGET_macosx_101000 = 10.10;
+MACOSX_DEPLOYMENT_TARGET_macosx_101100 = 10.11;
+MACOSX_DEPLOYMENT_TARGET_macosx_101200 = 10.12;
+MACOSX_DEPLOYMENT_TARGET_macosx_101300 = 10.13;
+MACOSX_DEPLOYMENT_TARGET_macosx_101400 = 10.14;
+
+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
+DEBUG_INFORMATION_FORMAT = dwarf;
+
+SDKROOT = $(SDKROOT_$(USE_INTERNAL_SDK));
+SDKROOT_ = macosx;
+SDKROOT_YES = macosx.internal;
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/Configurations/bmalloc.xcconfig b/weex_core/Source/android/jsengine/dependence/bmalloc/Configurations/bmalloc.xcconfig
new file mode 100644
index 0000000000..747bcb6836
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/Configurations/bmalloc.xcconfig
@@ -0,0 +1,30 @@
+// Copyright (C) 2014 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+EXECUTABLE_PREFIX = lib;
+INSTALL_PATH = /usr/local/lib;
+PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/bmalloc;
+PRODUCT_NAME = bmalloc;
+
+GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+STRIP_INSTALLED_PRODUCT = NO;
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/Configurations/mbmalloc.xcconfig b/weex_core/Source/android/jsengine/dependence/bmalloc/Configurations/mbmalloc.xcconfig
new file mode 100644
index 0000000000..513686e98d
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/Configurations/mbmalloc.xcconfig
@@ -0,0 +1,28 @@
+// Copyright (C) 2014 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+EXECUTABLE_PREFIX = lib;
+INSTALL_PATH = /usr/local/lib;
+PRODUCT_NAME = mbmalloc;
+
+GCC_SYMBOLS_PRIVATE_EXTERN = YES;
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/Makefile b/weex_core/Source/android/jsengine/dependence/bmalloc/Makefile
new file mode 100644
index 0000000000..cb4c11a57c
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/Makefile
@@ -0,0 +1 @@
+include ../Makefile.shared
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc.xcodeproj/project.pbxproj b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..aa02086774
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc.xcodeproj/project.pbxproj
@@ -0,0 +1,562 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1400274918F89C1300115C97 /* Heap.h in Headers */ = {isa = PBXBuildFile; fileRef = 14DA320C18875B09007269E0 /* Heap.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 1400274A18F89C2300115C97 /* VMHeap.h in Headers */ = {isa = PBXBuildFile; fileRef = 144F7BFC18BFC517003537F3 /* VMHeap.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 140FA00319CE429C00FFD3C8 /* BumpRange.h in Headers */ = {isa = PBXBuildFile; fileRef = 140FA00219CE429C00FFD3C8 /* BumpRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 140FA00519CE4B6800FFD3C8 /* LineMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 140FA00419CE4B6800FFD3C8 /* LineMetadata.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 141D9B001C8E51C0000ABBA0 /* List.h in Headers */ = {isa = PBXBuildFile; fileRef = 141D9AFF1C8E51C0000ABBA0 /* List.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 142B44361E2839E7001DA6E9 /* DebugHeap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 142B44341E2839E7001DA6E9 /* DebugHeap.cpp */; };
+ 142B44371E2839E7001DA6E9 /* DebugHeap.h in Headers */ = {isa = PBXBuildFile; fileRef = 142B44351E2839E7001DA6E9 /* DebugHeap.h */; };
+ 143CB81C19022BC900B16A45 /* StaticMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 143CB81A19022BC900B16A45 /* StaticMutex.cpp */; };
+ 143CB81D19022BC900B16A45 /* StaticMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 143CB81B19022BC900B16A45 /* StaticMutex.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 1440AFCB1A95261100837FAA /* Zone.h in Headers */ = {isa = PBXBuildFile; fileRef = 1440AFCA1A95261100837FAA /* Zone.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 1440AFCD1A9527AF00837FAA /* Zone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1440AFCC1A9527AF00837FAA /* Zone.cpp */; };
+ 1448C30018F3754600502839 /* mbmalloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1448C2FF18F3754300502839 /* mbmalloc.cpp */; };
+ 1448C30118F3754C00502839 /* bmalloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 1448C2FE18F3754300502839 /* bmalloc.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 144BE11F1CA346520099C8C0 /* Object.h in Headers */ = {isa = PBXBuildFile; fileRef = 144BE11E1CA346520099C8C0 /* Object.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 144C07F41C7B70260051BB6A /* LargeMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 144C07F21C7B70260051BB6A /* LargeMap.cpp */; };
+ 144C07F51C7B70260051BB6A /* LargeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 144C07F31C7B70260051BB6A /* LargeMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 147DC6E31CA5B70B00724E8D /* Chunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 147DC6E21CA5B70B00724E8D /* Chunk.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14895D911A3A319C0006235D /* Environment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14895D8F1A3A319C0006235D /* Environment.cpp */; };
+ 14895D921A3A319C0006235D /* Environment.h in Headers */ = {isa = PBXBuildFile; fileRef = 14895D901A3A319C0006235D /* Environment.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 148EFAE81D6B953B008E721E /* ScopeExit.h in Headers */ = {isa = PBXBuildFile; fileRef = 148EFAE61D6B953B008E721E /* ScopeExit.h */; };
+ 14C8992B1CC485E70027A057 /* Map.h in Headers */ = {isa = PBXBuildFile; fileRef = 14C8992A1CC485E70027A057 /* Map.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14C8992D1CC578330027A057 /* LargeRange.h in Headers */ = {isa = PBXBuildFile; fileRef = 14C8992C1CC578330027A057 /* LargeRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14C919C918FCC59F0028DB43 /* BPlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = 14C919C818FCC59F0028DB43 /* BPlatform.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14CC394C18EA8858004AFE34 /* libbmalloc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14F271BE18EA3963008C152F /* libbmalloc.a */; };
+ 14DD789018F48CEB00950702 /* Sizes.h in Headers */ = {isa = PBXBuildFile; fileRef = 145F6874179DF84100D65598 /* Sizes.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD789318F48D0F00950702 /* ObjectType.h in Headers */ = {isa = PBXBuildFile; fileRef = 1485656018A43DBA00ED6942 /* ObjectType.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD789818F48D4A00950702 /* Allocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 145F6856179DC8CA00D65598 /* Allocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD789918F48D4A00950702 /* Cache.h in Headers */ = {isa = PBXBuildFile; fileRef = 144469E517A46BFE00F9EA1D /* Cache.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD789A18F48D4A00950702 /* Deallocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 145F685A179DC90200D65598 /* Deallocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD789C18F48D4A00950702 /* BumpAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 1413E462189DE1CD00546D68 /* BumpAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78BC18F48D6B00950702 /* SmallLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 1452478618BC757C00F80098 /* SmallLine.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78BD18F48D6B00950702 /* SmallPage.h in Headers */ = {isa = PBXBuildFile; fileRef = 143E29ED18CAE90500FE8A0F /* SmallPage.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78C518F48D7500950702 /* Algorithm.h in Headers */ = {isa = PBXBuildFile; fileRef = 1421A87718EE462A00B4DD68 /* Algorithm.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78C618F48D7500950702 /* AsyncTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 1417F65218BA88A00076FA3F /* AsyncTask.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78C718F48D7500950702 /* BAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = 1413E468189EEDE400546D68 /* BAssert.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78C818F48D7500950702 /* FixedVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D9DB4517F2447100EAAB79 /* FixedVector.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78C918F48D7500950702 /* Inline.h in Headers */ = {isa = PBXBuildFile; fileRef = 1413E460189DCE1E00546D68 /* Inline.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78CA18F48D7500950702 /* Mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 144DCED617A649D90093B2F2 /* Mutex.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78CB18F48D7500950702 /* PerProcess.h in Headers */ = {isa = PBXBuildFile; fileRef = 14446A0717A61FA400F9EA1D /* PerProcess.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78CC18F48D7500950702 /* PerThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 144469FD17A61F1F00F9EA1D /* PerThread.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78CD18F48D7500950702 /* Range.h in Headers */ = {isa = PBXBuildFile; fileRef = 145F6878179E3A4400D65598 /* Range.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78CE18F48D7500950702 /* Syscall.h in Headers */ = {isa = PBXBuildFile; fileRef = 1417F64F18B7280C0076FA3F /* Syscall.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78CF18F48D7500950702 /* Vector.h in Headers */ = {isa = PBXBuildFile; fileRef = 1479E21217A1A255006D4E9D /* Vector.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DD78D018F48D7500950702 /* VMAllocate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1479E21417A1A63E006D4E9D /* VMAllocate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14F271C318EA3978008C152F /* Allocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 145F6855179DC8CA00D65598 /* Allocator.cpp */; };
+ 14F271C418EA397B008C152F /* Cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 144469E417A46BFE00F9EA1D /* Cache.cpp */; };
+ 14F271C518EA397E008C152F /* Deallocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 145F6859179DC90200D65598 /* Deallocator.cpp */; };
+ 14F271C718EA3990008C152F /* Heap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14DA320E18875D9F007269E0 /* Heap.cpp */; };
+ 14F271C818EA3990008C152F /* ObjectType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14105E8318E14374003A106E /* ObjectType.cpp */; };
+ 14F271C918EA3990008C152F /* VMHeap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 144F7BFB18BFC517003537F3 /* VMHeap.cpp */; };
+ 4426E2801C838EE0008EB042 /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4426E27E1C838EE0008EB042 /* Logging.cpp */; };
+ 4426E2811C838EE0008EB042 /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 4426E27F1C838EE0008EB042 /* Logging.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 4426E2831C839547008EB042 /* BSoftLinking.h in Headers */ = {isa = PBXBuildFile; fileRef = 4426E2821C839547008EB042 /* BSoftLinking.h */; };
+ 6599C5CC1EC3F15900A2F7BB /* AvailableMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6599C5CA1EC3F15900A2F7BB /* AvailableMemory.cpp */; };
+ 6599C5CD1EC3F15900A2F7BB /* AvailableMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 6599C5CB1EC3F15900A2F7BB /* AvailableMemory.h */; settings = {ATTRIBUTES = (Private, ); }; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 14CC394D18EA8861004AFE34 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 145F6837179DC45F00D65598 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 14F271BD18EA3963008C152F;
+ remoteInfo = bmalloc;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 140FA00219CE429C00FFD3C8 /* BumpRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BumpRange.h; path = bmalloc/BumpRange.h; sourceTree = "<group>"; };
+ 140FA00419CE4B6800FFD3C8 /* LineMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LineMetadata.h; path = bmalloc/LineMetadata.h; sourceTree = "<group>"; };
+ 14105E8318E14374003A106E /* ObjectType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjectType.cpp; path = bmalloc/ObjectType.cpp; sourceTree = "<group>"; };
+ 1413E460189DCE1E00546D68 /* Inline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Inline.h; path = bmalloc/Inline.h; sourceTree = "<group>"; };
+ 1413E462189DE1CD00546D68 /* BumpAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BumpAllocator.h; path = bmalloc/BumpAllocator.h; sourceTree = "<group>"; };
+ 1413E468189EEDE400546D68 /* BAssert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BAssert.h; path = bmalloc/BAssert.h; sourceTree = "<group>"; };
+ 1417F64F18B7280C0076FA3F /* Syscall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Syscall.h; path = bmalloc/Syscall.h; sourceTree = "<group>"; };
+ 1417F65218BA88A00076FA3F /* AsyncTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AsyncTask.h; path = bmalloc/AsyncTask.h; sourceTree = "<group>"; };
+ 141D9AFF1C8E51C0000ABBA0 /* List.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = List.h; path = bmalloc/List.h; sourceTree = "<group>"; };
+ 1421A87718EE462A00B4DD68 /* Algorithm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Algorithm.h; path = bmalloc/Algorithm.h; sourceTree = "<group>"; };
+ 142B44341E2839E7001DA6E9 /* DebugHeap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DebugHeap.cpp; path = bmalloc/DebugHeap.cpp; sourceTree = "<group>"; };
+ 142B44351E2839E7001DA6E9 /* DebugHeap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DebugHeap.h; path = bmalloc/DebugHeap.h; sourceTree = "<group>"; };
+ 143CB81A19022BC900B16A45 /* StaticMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StaticMutex.cpp; path = bmalloc/StaticMutex.cpp; sourceTree = "<group>"; };
+ 143CB81B19022BC900B16A45 /* StaticMutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StaticMutex.h; path = bmalloc/StaticMutex.h; sourceTree = "<group>"; };
+ 143E29ED18CAE90500FE8A0F /* SmallPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SmallPage.h; path = bmalloc/SmallPage.h; sourceTree = "<group>"; };
+ 1440AFCA1A95261100837FAA /* Zone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Zone.h; path = bmalloc/Zone.h; sourceTree = "<group>"; };
+ 1440AFCC1A9527AF00837FAA /* Zone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Zone.cpp; path = bmalloc/Zone.cpp; sourceTree = "<group>"; };
+ 144469E417A46BFE00F9EA1D /* Cache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = Cache.cpp; path = bmalloc/Cache.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 144469E517A46BFE00F9EA1D /* Cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = Cache.h; path = bmalloc/Cache.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 144469FD17A61F1F00F9EA1D /* PerThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = PerThread.h; path = bmalloc/PerThread.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 14446A0717A61FA400F9EA1D /* PerProcess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PerProcess.h; path = bmalloc/PerProcess.h; sourceTree = "<group>"; };
+ 1448C2FE18F3754300502839 /* bmalloc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = bmalloc.h; path = bmalloc/bmalloc.h; sourceTree = "<group>"; };
+ 1448C2FF18F3754300502839 /* mbmalloc.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = mbmalloc.cpp; path = bmalloc/mbmalloc.cpp; sourceTree = "<group>"; };
+ 144BE11E1CA346520099C8C0 /* Object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Object.h; path = bmalloc/Object.h; sourceTree = "<group>"; };
+ 144C07F21C7B70260051BB6A /* LargeMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LargeMap.cpp; path = bmalloc/LargeMap.cpp; sourceTree = "<group>"; };
+ 144C07F31C7B70260051BB6A /* LargeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LargeMap.h; path = bmalloc/LargeMap.h; sourceTree = "<group>"; };
+ 144DCED617A649D90093B2F2 /* Mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Mutex.h; path = bmalloc/Mutex.h; sourceTree = "<group>"; };
+ 144F7BFB18BFC517003537F3 /* VMHeap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VMHeap.cpp; path = bmalloc/VMHeap.cpp; sourceTree = "<group>"; };
+ 144F7BFC18BFC517003537F3 /* VMHeap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VMHeap.h; path = bmalloc/VMHeap.h; sourceTree = "<group>"; };
+ 1452478618BC757C00F80098 /* SmallLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SmallLine.h; path = bmalloc/SmallLine.h; sourceTree = "<group>"; };
+ 145F6855179DC8CA00D65598 /* Allocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = Allocator.cpp; path = bmalloc/Allocator.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 145F6856179DC8CA00D65598 /* Allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = Allocator.h; path = bmalloc/Allocator.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 145F6859179DC90200D65598 /* Deallocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = Deallocator.cpp; path = bmalloc/Deallocator.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 145F685A179DC90200D65598 /* Deallocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = Deallocator.h; path = bmalloc/Deallocator.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 145F6874179DF84100D65598 /* Sizes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Sizes.h; path = bmalloc/Sizes.h; sourceTree = "<group>"; };
+ 145F6878179E3A4400D65598 /* Range.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = Range.h; path = bmalloc/Range.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 1479E21217A1A255006D4E9D /* Vector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = Vector.h; path = bmalloc/Vector.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 1479E21417A1A63E006D4E9D /* VMAllocate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = VMAllocate.h; path = bmalloc/VMAllocate.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 147DC6E21CA5B70B00724E8D /* Chunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Chunk.h; path = bmalloc/Chunk.h; sourceTree = "<group>"; };
+ 1485656018A43DBA00ED6942 /* ObjectType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjectType.h; path = bmalloc/ObjectType.h; sourceTree = "<group>"; };
+ 14895D8F1A3A319C0006235D /* Environment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Environment.cpp; path = bmalloc/Environment.cpp; sourceTree = "<group>"; };
+ 14895D901A3A319C0006235D /* Environment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Environment.h; path = bmalloc/Environment.h; sourceTree = "<group>"; };
+ 148EFAE61D6B953B008E721E /* ScopeExit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScopeExit.h; path = bmalloc/ScopeExit.h; sourceTree = "<group>"; };
+ 14B650C518F39F4800751968 /* Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; };
+ 14B650C618F39F4800751968 /* bmalloc.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = bmalloc.xcconfig; sourceTree = "<group>"; };
+ 14B650C718F39F4800751968 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = "<group>"; };
+ 14B650C918F3A04200751968 /* mbmalloc.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = mbmalloc.xcconfig; sourceTree = "<group>"; };
+ 14C8992A1CC485E70027A057 /* Map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Map.h; path = bmalloc/Map.h; sourceTree = "<group>"; };
+ 14C8992C1CC578330027A057 /* LargeRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LargeRange.h; path = bmalloc/LargeRange.h; sourceTree = "<group>"; };
+ 14C919C818FCC59F0028DB43 /* BPlatform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BPlatform.h; path = bmalloc/BPlatform.h; sourceTree = "<group>"; };
+ 14CC394418EA8743004AFE34 /* libmbmalloc.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libmbmalloc.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+ 14D9DB4517F2447100EAAB79 /* FixedVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = FixedVector.h; path = bmalloc/FixedVector.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 14DA320C18875B09007269E0 /* Heap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Heap.h; path = bmalloc/Heap.h; sourceTree = "<group>"; };
+ 14DA320E18875D9F007269E0 /* Heap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Heap.cpp; path = bmalloc/Heap.cpp; sourceTree = "<group>"; };
+ 14F271BE18EA3963008C152F /* libbmalloc.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libbmalloc.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4426E27E1C838EE0008EB042 /* Logging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Logging.cpp; path = bmalloc/Logging.cpp; sourceTree = "<group>"; };
+ 4426E27F1C838EE0008EB042 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = bmalloc/Logging.h; sourceTree = "<group>"; };
+ 4426E2821C839547008EB042 /* BSoftLinking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BSoftLinking.h; path = bmalloc/darwin/BSoftLinking.h; sourceTree = "<group>"; };
+ 6599C5CA1EC3F15900A2F7BB /* AvailableMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AvailableMemory.cpp; path = bmalloc/AvailableMemory.cpp; sourceTree = "<group>"; };
+ 6599C5CB1EC3F15900A2F7BB /* AvailableMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AvailableMemory.h; path = bmalloc/AvailableMemory.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 14CC394118EA8743004AFE34 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 14CC394C18EA8858004AFE34 /* libbmalloc.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 14F271BB18EA3963008C152F /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 1448C2FD18F3752B00502839 /* api */ = {
+ isa = PBXGroup;
+ children = (
+ 1448C2FE18F3754300502839 /* bmalloc.h */,
+ 1448C2FF18F3754300502839 /* mbmalloc.cpp */,
+ );
+ name = api;
+ sourceTree = "<group>";
+ };
+ 145F6836179DC45F00D65598 = {
+ isa = PBXGroup;
+ children = (
+ 1448C2FD18F3752B00502839 /* api */,
+ 14D9DB4D17F2865C00EAAB79 /* cache */,
+ 14B650C418F39F4800751968 /* Configurations */,
+ 14D9DB4E17F2866E00EAAB79 /* heap */,
+ 147AAA9C18CE6010002201E4 /* heap: large */,
+ 147AAA9A18CE5FD3002201E4 /* heap: small */,
+ 145F6840179DC45F00D65598 /* Products */,
+ 14D9DB4F17F2868900EAAB79 /* stdlib */,
+ );
+ sourceTree = "<group>";
+ };
+ 145F6840179DC45F00D65598 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 14F271BE18EA3963008C152F /* libbmalloc.a */,
+ 14CC394418EA8743004AFE34 /* libmbmalloc.dylib */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 147AAA9A18CE5FD3002201E4 /* heap: small */ = {
+ isa = PBXGroup;
+ children = (
+ 1452478618BC757C00F80098 /* SmallLine.h */,
+ 143E29ED18CAE90500FE8A0F /* SmallPage.h */,
+ );
+ name = "heap: small";
+ sourceTree = "<group>";
+ };
+ 147AAA9C18CE6010002201E4 /* heap: large */ = {
+ isa = PBXGroup;
+ children = (
+ 144C07F21C7B70260051BB6A /* LargeMap.cpp */,
+ 144C07F31C7B70260051BB6A /* LargeMap.h */,
+ 14C8992C1CC578330027A057 /* LargeRange.h */,
+ );
+ name = "heap: large";
+ sourceTree = "<group>";
+ };
+ 14B650C418F39F4800751968 /* Configurations */ = {
+ isa = PBXGroup;
+ children = (
+ 14B650C518F39F4800751968 /* Base.xcconfig */,
+ 14B650C618F39F4800751968 /* bmalloc.xcconfig */,
+ 14B650C718F39F4800751968 /* DebugRelease.xcconfig */,
+ 14B650C918F3A04200751968 /* mbmalloc.xcconfig */,
+ );
+ path = Configurations;
+ sourceTree = "<group>";
+ };
+ 14D9DB4D17F2865C00EAAB79 /* cache */ = {
+ isa = PBXGroup;
+ children = (
+ 145F6855179DC8CA00D65598 /* Allocator.cpp */,
+ 145F6856179DC8CA00D65598 /* Allocator.h */,
+ 1413E462189DE1CD00546D68 /* BumpAllocator.h */,
+ 144469E417A46BFE00F9EA1D /* Cache.cpp */,
+ 144469E517A46BFE00F9EA1D /* Cache.h */,
+ 145F6859179DC90200D65598 /* Deallocator.cpp */,
+ 145F685A179DC90200D65598 /* Deallocator.h */,
+ );
+ name = cache;
+ sourceTree = "<group>";
+ };
+ 14D9DB4E17F2866E00EAAB79 /* heap */ = {
+ isa = PBXGroup;
+ children = (
+ 140FA00219CE429C00FFD3C8 /* BumpRange.h */,
+ 147DC6E21CA5B70B00724E8D /* Chunk.h */,
+ 142B44341E2839E7001DA6E9 /* DebugHeap.cpp */,
+ 142B44351E2839E7001DA6E9 /* DebugHeap.h */,
+ 14895D8F1A3A319C0006235D /* Environment.cpp */,
+ 14895D901A3A319C0006235D /* Environment.h */,
+ 14DA320E18875D9F007269E0 /* Heap.cpp */,
+ 14DA320C18875B09007269E0 /* Heap.h */,
+ 140FA00419CE4B6800FFD3C8 /* LineMetadata.h */,
+ 144BE11E1CA346520099C8C0 /* Object.h */,
+ 14105E8318E14374003A106E /* ObjectType.cpp */,
+ 1485656018A43DBA00ED6942 /* ObjectType.h */,
+ 145F6874179DF84100D65598 /* Sizes.h */,
+ 144F7BFB18BFC517003537F3 /* VMHeap.cpp */,
+ 144F7BFC18BFC517003537F3 /* VMHeap.h */,
+ 1440AFCC1A9527AF00837FAA /* Zone.cpp */,
+ 1440AFCA1A95261100837FAA /* Zone.h */,
+ );
+ name = heap;
+ sourceTree = "<group>";
+ };
+ 14D9DB4F17F2868900EAAB79 /* stdlib */ = {
+ isa = PBXGroup;
+ children = (
+ 4408F2961C9896C40012EC64 /* darwin */,
+ 1421A87718EE462A00B4DD68 /* Algorithm.h */,
+ 1417F65218BA88A00076FA3F /* AsyncTask.h */,
+ 6599C5CA1EC3F15900A2F7BB /* AvailableMemory.cpp */,
+ 6599C5CB1EC3F15900A2F7BB /* AvailableMemory.h */,
+ 1413E468189EEDE400546D68 /* BAssert.h */,
+ 14C919C818FCC59F0028DB43 /* BPlatform.h */,
+ 14D9DB4517F2447100EAAB79 /* FixedVector.h */,
+ 1413E460189DCE1E00546D68 /* Inline.h */,
+ 141D9AFF1C8E51C0000ABBA0 /* List.h */,
+ 4426E27E1C838EE0008EB042 /* Logging.cpp */,
+ 4426E27F1C838EE0008EB042 /* Logging.h */,
+ 14C8992A1CC485E70027A057 /* Map.h */,
+ 144DCED617A649D90093B2F2 /* Mutex.h */,
+ 14446A0717A61FA400F9EA1D /* PerProcess.h */,
+ 144469FD17A61F1F00F9EA1D /* PerThread.h */,
+ 145F6878179E3A4400D65598 /* Range.h */,
+ 148EFAE61D6B953B008E721E /* ScopeExit.h */,
+ 143CB81A19022BC900B16A45 /* StaticMutex.cpp */,
+ 143CB81B19022BC900B16A45 /* StaticMutex.h */,
+ 1417F64F18B7280C0076FA3F /* Syscall.h */,
+ 1479E21217A1A255006D4E9D /* Vector.h */,
+ 1479E21417A1A63E006D4E9D /* VMAllocate.h */,
+ );
+ name = stdlib;
+ sourceTree = "<group>";
+ };
+ 4408F2961C9896C40012EC64 /* darwin */ = {
+ isa = PBXGroup;
+ children = (
+ 4426E2821C839547008EB042 /* BSoftLinking.h */,
+ );
+ name = darwin;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ 14CC394218EA8743004AFE34 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 14F271BC18EA3963008C152F /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 14DD78C518F48D7500950702 /* Algorithm.h in Headers */,
+ 14DD789818F48D4A00950702 /* Allocator.h in Headers */,
+ 14DD78C618F48D7500950702 /* AsyncTask.h in Headers */,
+ 6599C5CD1EC3F15900A2F7BB /* AvailableMemory.h in Headers */,
+ 14DD78C718F48D7500950702 /* BAssert.h in Headers */,
+ 1448C30118F3754C00502839 /* bmalloc.h in Headers */,
+ 14C919C918FCC59F0028DB43 /* BPlatform.h in Headers */,
+ 4426E2831C839547008EB042 /* BSoftLinking.h in Headers */,
+ 14DD789C18F48D4A00950702 /* BumpAllocator.h in Headers */,
+ 140FA00319CE429C00FFD3C8 /* BumpRange.h in Headers */,
+ 14DD789918F48D4A00950702 /* Cache.h in Headers */,
+ 147DC6E31CA5B70B00724E8D /* Chunk.h in Headers */,
+ 14DD789A18F48D4A00950702 /* Deallocator.h in Headers */,
+ 14895D921A3A319C0006235D /* Environment.h in Headers */,
+ 14DD78C818F48D7500950702 /* FixedVector.h in Headers */,
+ 1400274918F89C1300115C97 /* Heap.h in Headers */,
+ 14DD78C918F48D7500950702 /* Inline.h in Headers */,
+ 144C07F51C7B70260051BB6A /* LargeMap.h in Headers */,
+ 14C8992D1CC578330027A057 /* LargeRange.h in Headers */,
+ 140FA00519CE4B6800FFD3C8 /* LineMetadata.h in Headers */,
+ 141D9B001C8E51C0000ABBA0 /* List.h in Headers */,
+ 4426E2811C838EE0008EB042 /* Logging.h in Headers */,
+ 14C8992B1CC485E70027A057 /* Map.h in Headers */,
+ 14DD78CA18F48D7500950702 /* Mutex.h in Headers */,
+ 144BE11F1CA346520099C8C0 /* Object.h in Headers */,
+ 14DD789318F48D0F00950702 /* ObjectType.h in Headers */,
+ 142B44371E2839E7001DA6E9 /* DebugHeap.h in Headers */,
+ 14DD78CB18F48D7500950702 /* PerProcess.h in Headers */,
+ 14DD78CC18F48D7500950702 /* PerThread.h in Headers */,
+ 14DD78CD18F48D7500950702 /* Range.h in Headers */,
+ 148EFAE81D6B953B008E721E /* ScopeExit.h in Headers */,
+ 14DD789018F48CEB00950702 /* Sizes.h in Headers */,
+ 14DD78BC18F48D6B00950702 /* SmallLine.h in Headers */,
+ 14DD78BD18F48D6B00950702 /* SmallPage.h in Headers */,
+ 143CB81D19022BC900B16A45 /* StaticMutex.h in Headers */,
+ 14DD78CE18F48D7500950702 /* Syscall.h in Headers */,
+ 14DD78CF18F48D7500950702 /* Vector.h in Headers */,
+ 14DD78D018F48D7500950702 /* VMAllocate.h in Headers */,
+ 1400274A18F89C2300115C97 /* VMHeap.h in Headers */,
+ 1440AFCB1A95261100837FAA /* Zone.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 14CC394318EA8743004AFE34 /* mbmalloc */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 14CC394518EA8743004AFE34 /* Build configuration list for PBXNativeTarget "mbmalloc" */;
+ buildPhases = (
+ 14CC394018EA8743004AFE34 /* Sources */,
+ 14CC394118EA8743004AFE34 /* Frameworks */,
+ 14CC394218EA8743004AFE34 /* Headers */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 14CC394E18EA8861004AFE34 /* PBXTargetDependency */,
+ );
+ name = mbmalloc;
+ productName = mbmalloc;
+ productReference = 14CC394418EA8743004AFE34 /* libmbmalloc.dylib */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ 14F271BD18EA3963008C152F /* bmalloc */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 14F271BF18EA3963008C152F /* Build configuration list for PBXNativeTarget "bmalloc" */;
+ buildPhases = (
+ 14F271BA18EA3963008C152F /* Sources */,
+ 14F271BB18EA3963008C152F /* Frameworks */,
+ 14F271BC18EA3963008C152F /* Headers */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = bmalloc;
+ productName = bmalloc;
+ productReference = 14F271BE18EA3963008C152F /* libbmalloc.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 145F6837179DC45F00D65598 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 0700;
+ LastUpgradeCheck = 0700;
+ };
+ buildConfigurationList = 145F683A179DC45F00D65598 /* Build configuration list for PBXProject "bmalloc" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 145F6836179DC45F00D65598;
+ productRefGroup = 145F6840179DC45F00D65598 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 14F271BD18EA3963008C152F /* bmalloc */,
+ 14CC394318EA8743004AFE34 /* mbmalloc */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 14CC394018EA8743004AFE34 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1448C30018F3754600502839 /* mbmalloc.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 14F271BA18EA3963008C152F /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 14F271C318EA3978008C152F /* Allocator.cpp in Sources */,
+ 14F271C418EA397B008C152F /* Cache.cpp in Sources */,
+ 14F271C518EA397E008C152F /* Deallocator.cpp in Sources */,
+ 14895D911A3A319C0006235D /* Environment.cpp in Sources */,
+ 14F271C718EA3990008C152F /* Heap.cpp in Sources */,
+ 144C07F41C7B70260051BB6A /* LargeMap.cpp in Sources */,
+ 4426E2801C838EE0008EB042 /* Logging.cpp in Sources */,
+ 142B44361E2839E7001DA6E9 /* DebugHeap.cpp in Sources */,
+ 14F271C818EA3990008C152F /* ObjectType.cpp in Sources */,
+ 6599C5CC1EC3F15900A2F7BB /* AvailableMemory.cpp in Sources */,
+ 143CB81C19022BC900B16A45 /* StaticMutex.cpp in Sources */,
+ 14F271C918EA3990008C152F /* VMHeap.cpp in Sources */,
+ 1440AFCD1A9527AF00837FAA /* Zone.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 14CC394E18EA8861004AFE34 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 14F271BD18EA3963008C152F /* bmalloc */;
+ targetProxy = 14CC394D18EA8861004AFE34 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 14202F0F18F37C15006C37DB /* Production */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 14B650C518F39F4800751968 /* Base.xcconfig */;
+ buildSettings = {
+ };
+ name = Production;
+ };
+ 14202F1018F37C15006C37DB /* Production */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 14B650C618F39F4800751968 /* bmalloc.xcconfig */;
+ buildSettings = {
+ };
+ name = Production;
+ };
+ 14202F1118F37C15006C37DB /* Production */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 14B650C918F3A04200751968 /* mbmalloc.xcconfig */;
+ buildSettings = {
+ };
+ name = Production;
+ };
+ 145F684A179DC45F00D65598 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 14B650C718F39F4800751968 /* DebugRelease.xcconfig */;
+ buildSettings = {
+ DEAD_CODE_STRIPPING = "$(DEAD_CODE_STRIPPING_debug)";
+ DEBUG_DEFINES = "$(DEBUG_DEFINES_debug)";
+ GCC_OPTIMIZATION_LEVEL = "$(GCC_OPTIMIZATION_LEVEL_debug)";
+ STRIP_INSTALLED_PRODUCT = "$(STRIP_INSTALLED_PRODUCT_debug)";
+ };
+ name = Debug;
+ };
+ 145F684B179DC45F00D65598 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 14B650C718F39F4800751968 /* DebugRelease.xcconfig */;
+ buildSettings = {
+ };
+ name = Release;
+ };
+ 14CC394618EA8743004AFE34 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 14B650C918F3A04200751968 /* mbmalloc.xcconfig */;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ 14CC394718EA8743004AFE34 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 14B650C918F3A04200751968 /* mbmalloc.xcconfig */;
+ buildSettings = {
+ };
+ name = Release;
+ };
+ 14F271C018EA3963008C152F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 14B650C618F39F4800751968 /* bmalloc.xcconfig */;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ 14F271C118EA3963008C152F /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 14B650C618F39F4800751968 /* bmalloc.xcconfig */;
+ buildSettings = {
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 145F683A179DC45F00D65598 /* Build configuration list for PBXProject "bmalloc" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 145F684A179DC45F00D65598 /* Debug */,
+ 145F684B179DC45F00D65598 /* Release */,
+ 14202F0F18F37C15006C37DB /* Production */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Production;
+ };
+ 14CC394518EA8743004AFE34 /* Build configuration list for PBXNativeTarget "mbmalloc" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 14CC394618EA8743004AFE34 /* Debug */,
+ 14CC394718EA8743004AFE34 /* Release */,
+ 14202F1118F37C15006C37DB /* Production */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Production;
+ };
+ 14F271BF18EA3963008C152F /* Build configuration list for PBXNativeTarget "bmalloc" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 14F271C018EA3963008C152F /* Debug */,
+ 14F271C118EA3963008C152F /* Release */,
+ 14202F1018F37C15006C37DB /* Production */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Production;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 145F6837179DC45F00D65598 /* Project object */;
+}
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Algorithm.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Algorithm.h
new file mode 100644
index 0000000000..ea247eebc8
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Algorithm.h
@@ -0,0 +1,121 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef Algorithm_h
+#define Algorithm_h
+
+#include "Algorithm.h"
+#include "BAssert.h"
+#include <algorithm>
+#include <cstdint>
+#include <cstddef>
+#include <limits>
+#include <type_traits>
+#include <chrono>
+
+namespace bmalloc {
+
+// Versions of min and max that are compatible with compile-time constants.
+template<typename T> inline constexpr T max(T a, T b)
+{
+ return a > b ? a : b;
+}
+
+template<typename T> inline constexpr T min(T a, T b)
+{
+ return a < b ? a : b;
+}
+
+template<typename T> inline constexpr T mask(T value, uintptr_t mask)
+{
+ return reinterpret_cast<T>(reinterpret_cast<uintptr_t>(value) & mask);
+}
+
+template<typename T> inline constexpr bool test(T value, uintptr_t mask)
+{
+ return !!(reinterpret_cast<uintptr_t>(value) & mask);
+}
+
+inline constexpr bool isPowerOfTwo(size_t size)
+{
+ return size && !(size & (size - 1));
+}
+
+template<typename T> inline T roundUpToMultipleOf(size_t divisor, T x)
+{
+ BASSERT(isPowerOfTwo(divisor));
+ return reinterpret_cast<T>((reinterpret_cast<uintptr_t>(x) + (divisor - 1)) & ~(divisor - 1));
+}
+
+template<size_t divisor, typename T> inline constexpr T roundUpToMultipleOf(T x)
+{
+ static_assert(isPowerOfTwo(divisor), "'divisor' must be a power of two.");
+ return roundUpToMultipleOf(divisor, x);
+}
+
+template<typename T> inline T roundDownToMultipleOf(size_t divisor, T x)
+{
+ BASSERT(isPowerOfTwo(divisor));
+ return reinterpret_cast<T>(mask(reinterpret_cast<uintptr_t>(x), ~(divisor - 1ul)));
+}
+
+template<size_t divisor, typename T> inline constexpr T roundDownToMultipleOf(T x)
+{
+ static_assert(isPowerOfTwo(divisor), "'divisor' must be a power of two.");
+ return roundDownToMultipleOf(divisor, x);
+}
+
+template<typename T> inline void divideRoundingUp(T numerator, T denominator, T& quotient, T& remainder)
+{
+ // We expect the compiler to emit a single divide instruction to extract both the quotient and the remainder.
+ quotient = numerator / denominator;
+ remainder = numerator % denominator;
+ if (remainder)
+ quotient += 1;
+}
+
+template<typename T> inline T divideRoundingUp(T numerator, T denominator)
+{
+ return (numerator + denominator - 1) / denominator;
+}
+
+template<typename T> inline T roundUpToMultipleOfNonPowerOfTwo(size_t divisor, T x)
+{
+ return divideRoundingUp(x, divisor) * divisor;
+}
+
+// Version of sizeof that returns 0 for empty classes.
+
+template<typename T> inline constexpr size_t sizeOf()
+{
+ return std::is_empty<T>::value ? 0 : sizeof(T);
+}
+
+template<typename T> inline constexpr size_t bitCount()
+{
+ return sizeof(T) * 8;
+}
+
+inline constexpr unsigned long log2(unsigned long value)
+{
+ return bitCount<unsigned long>() - 1 - __builtin_clzl(value);
+}
+
+} // namespace bmalloc
+
+#endif // Algorithm_h
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Allocator.cpp b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Allocator.cpp
new file mode 100644
index 0000000000..a2da07305f
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Allocator.cpp
@@ -0,0 +1,195 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "Allocator.h"
+#include "BAssert.h"
+#include "Chunk.h"
+#include "Deallocator.h"
+#include "DebugHeap.h"
+#include "Heap.h"
+#include "PerProcess.h"
+#include "Sizes.h"
+#include <algorithm>
+#include <cstdlib>
+
+using namespace std;
+
+namespace bmalloc {
+
+Allocator::Allocator(Heap* heap, Deallocator& deallocator)
+ : m_debugHeap(heap->debugHeap())
+ , m_deallocator(deallocator)
+{
+ for (size_t sizeClass = 0; sizeClass < sizeClassCount; ++sizeClass)
+ m_bumpAllocators[sizeClass].init(objectSize(sizeClass));
+}
+
+Allocator::~Allocator()
+{
+ scavenge();
+}
+
+void* Allocator::tryAllocate(size_t size)
+{
+ if (m_debugHeap)
+ return m_debugHeap->malloc(size);
+
+ if (size <= smallMax)
+ return allocate(size);
+
+ std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
+ return PerProcess<Heap>::getFastCase()->tryAllocateLarge(lock, alignment, size);
+}
+
+void* Allocator::allocate(size_t alignment, size_t size)
+{
+ bool crashOnFailure = true;
+ return allocateImpl(alignment, size, crashOnFailure);
+}
+
+void* Allocator::tryAllocate(size_t alignment, size_t size)
+{
+ bool crashOnFailure = false;
+ return allocateImpl(alignment, size, crashOnFailure);
+}
+
+void* Allocator::allocateImpl(size_t alignment, size_t size, bool crashOnFailure)
+{
+ BASSERT(isPowerOfTwo(alignment));
+
+ if (m_debugHeap)
+ return m_debugHeap->memalign(alignment, size, crashOnFailure);
+
+ if (!size)
+ size = alignment;
+
+ if (size <= smallMax && alignment <= smallMax)
+ return allocate(roundUpToMultipleOf(alignment, size));
+
+ std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
+ Heap* heap = PerProcess<Heap>::getFastCase();
+ if (crashOnFailure)
+ return heap->allocateLarge(lock, alignment, size);
+ return heap->tryAllocateLarge(lock, alignment, size);
+}
+
+void* Allocator::reallocate(void* object, size_t newSize)
+{
+ if (m_debugHeap)
+ return m_debugHeap->realloc(object, newSize);
+
+ size_t oldSize = 0;
+ switch (objectType(object)) {
+ case ObjectType::Small: {
+ BASSERT(objectType(nullptr) == ObjectType::Small);
+ if (!object)
+ break;
+
+ size_t sizeClass = Object(object).page()->sizeClass();
+ oldSize = objectSize(sizeClass);
+ break;
+ }
+ case ObjectType::Large: {
+ std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
+ oldSize = PerProcess<Heap>::getFastCase()->largeSize(lock, object);
+
+ if (newSize < oldSize && newSize > smallMax) {
+ PerProcess<Heap>::getFastCase()->shrinkLarge(lock, Range(object, oldSize), newSize);
+ return object;
+ }
+ break;
+ }
+ }
+
+ void* result = allocate(newSize);
+ size_t copySize = std::min(oldSize, newSize);
+ memcpy(result, object, copySize);
+ m_deallocator.deallocate(object);
+ return result;
+}
+
+void Allocator::scavenge()
+{
+ for (size_t sizeClass = 0; sizeClass < sizeClassCount; ++sizeClass) {
+ BumpAllocator& allocator = m_bumpAllocators[sizeClass];
+ BumpRangeCache& bumpRangeCache = m_bumpRangeCaches[sizeClass];
+
+ while (allocator.canAllocate())
+ m_deallocator.deallocate(allocator.allocate());
+
+ while (bumpRangeCache.size()) {
+ allocator.refill(bumpRangeCache.pop());
+ while (allocator.canAllocate())
+ m_deallocator.deallocate(allocator.allocate());
+ }
+
+ allocator.clear();
+ }
+}
+
+NO_INLINE void Allocator::refillAllocatorSlowCase(BumpAllocator& allocator, size_t sizeClass)
+{
+ BumpRangeCache& bumpRangeCache = m_bumpRangeCaches[sizeClass];
+
+ std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
+ m_deallocator.processObjectLog(lock);
+ PerProcess<Heap>::getFastCase()->allocateSmallBumpRanges(lock, sizeClass, allocator, bumpRangeCache);
+}
+
+INLINE void Allocator::refillAllocator(BumpAllocator& allocator, size_t sizeClass)
+{
+ BumpRangeCache& bumpRangeCache = m_bumpRangeCaches[sizeClass];
+ if (!bumpRangeCache.size())
+ return refillAllocatorSlowCase(allocator, sizeClass);
+ return allocator.refill(bumpRangeCache.pop());
+}
+
+NO_INLINE void* Allocator::allocateLarge(size_t size)
+{
+ std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
+ return PerProcess<Heap>::getFastCase()->allocateLarge(lock, alignment, size);
+}
+
+NO_INLINE void* Allocator::allocateLogSizeClass(size_t size)
+{
+ size_t sizeClass = bmalloc::sizeClass(size);
+ BumpAllocator& allocator = m_bumpAllocators[sizeClass];
+ if (!allocator.canAllocate())
+ refillAllocator(allocator, sizeClass);
+ return allocator.allocate();
+}
+
+void* Allocator::allocateSlowCase(size_t size)
+{
+ if (m_debugHeap)
+ return m_debugHeap->malloc(size);
+
+ if (size <= maskSizeClassMax) {
+ size_t sizeClass = bmalloc::maskSizeClass(size);
+ BumpAllocator& allocator = m_bumpAllocators[sizeClass];
+ refillAllocator(allocator, sizeClass);
+ return allocator.allocate();
+ }
+
+ if (size <= smallMax)
+ return allocateLogSizeClass(size);
+
+ return allocateLarge(size);
+}
+
+} // namespace bmalloc
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Allocator.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Allocator.h
new file mode 100644
index 0000000000..bb44cca6f0
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Allocator.h
@@ -0,0 +1,88 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef Allocator_h
+#define Allocator_h
+
+#include "BumpAllocator.h"
+#include <array>
+
+namespace bmalloc {
+
+class Deallocator;
+class DebugHeap;
+class Heap;
+
+// Per-cache object allocator.
+
+class Allocator {
+public:
+ Allocator(Heap*, Deallocator&);
+ ~Allocator();
+
+ void* tryAllocate(size_t);
+ void* allocate(size_t);
+ void* tryAllocate(size_t alignment, size_t);
+ void* allocate(size_t alignment, size_t);
+ void* reallocate(void*, size_t);
+
+ void scavenge();
+
+private:
+ void* allocateImpl(size_t alignment, size_t, bool crashOnFailure);
+
+ bool allocateFastCase(size_t, void*&);
+ void* allocateSlowCase(size_t);
+
+ void* allocateLogSizeClass(size_t);
+ void* allocateLarge(size_t);
+
+ void refillAllocator(BumpAllocator&, size_t sizeClass);
+ void refillAllocatorSlowCase(BumpAllocator&, size_t sizeClass);
+
+ std::array<BumpAllocator, sizeClassCount> m_bumpAllocators;
+ std::array<BumpRangeCache, sizeClassCount> m_bumpRangeCaches;
+
+ DebugHeap* m_debugHeap;
+ Deallocator& m_deallocator;
+};
+
+inline bool Allocator::allocateFastCase(size_t size, void*& object)
+{
+ if (size > maskSizeClassMax)
+ return false;
+
+ BumpAllocator& allocator = m_bumpAllocators[maskSizeClass(size)];
+ if (!allocator.canAllocate())
+ return false;
+
+ object = allocator.allocate();
+ return true;
+}
+
+inline void* Allocator::allocate(size_t size)
+{
+ void* object;
+ if (!allocateFastCase(size, object))
+ return allocateSlowCase(size);
+ return object;
+}
+
+} // namespace bmalloc
+
+#endif // Allocator_h
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/AsyncTask.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/AsyncTask.h
new file mode 100644
index 0000000000..8d5f48712f
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/AsyncTask.h
@@ -0,0 +1,137 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef AsyncTask_h
+#define AsyncTask_h
+
+#include "BAssert.h"
+#include "Inline.h"
+#include "Mutex.h"
+#include "Sizes.h"
+#include <atomic>
+#include <condition_variable>
+#include <thread>
+
+namespace bmalloc {
+
+template<typename Object, typename Function>
+class AsyncTask {
+public:
+ AsyncTask(Object&, const Function&);
+ ~AsyncTask();
+
+ bool willRun() { return m_state == State::Run; }
+ void run();
+
+ bool willRunSoon() { return m_state > State::Sleep; }
+ void runSoon();
+
+private:
+ enum class State { Sleep, Run, RunSoon };
+
+ void runSlowCase();
+ void runSoonSlowCase();
+
+ static void threadEntryPoint(AsyncTask*);
+ void threadRunLoop();
+
+ std::atomic<State> m_state;
+
+ Mutex m_conditionMutex;
+ std::condition_variable_any m_condition;
+
+ std::thread m_thread;
+
+ Object& m_object;
+ Function m_function;
+};
+
+template<typename Object, typename Function>
+AsyncTask<Object, Function>::AsyncTask(Object& object, const Function& function)
+ : m_state(State::Sleep)
+ , m_condition()
+ , m_thread(std::thread(&AsyncTask::threadEntryPoint, this))
+ , m_object(object)
+ , m_function(function)
+{
+}
+
+template<typename Object, typename Function>
+AsyncTask<Object, Function>::~AsyncTask()
+{
+ // We'd like to mark our destructor deleted but C++ won't allow it because
+ // we are an automatic member of Heap.
+ RELEASE_BASSERT(0);
+}
+
+template<typename Object, typename Function>
+void AsyncTask<Object, Function>::run()
+{
+ m_state = State::Run;
+
+ std::lock_guard<Mutex> lock(m_conditionMutex);
+ m_condition.notify_all();
+}
+
+template<typename Object, typename Function>
+void AsyncTask<Object, Function>::runSoon()
+{
+ m_state = State::RunSoon;
+
+ std::lock_guard<Mutex> lock(m_conditionMutex);
+ m_condition.notify_all();
+}
+
+template<typename Object, typename Function>
+void AsyncTask<Object, Function>::threadEntryPoint(AsyncTask* asyncTask)
+{
+#if BOS(DARWIN)
+ pthread_set_qos_class_self_np(QOS_CLASS_USER_INTERACTIVE, 0);
+#endif
+
+ asyncTask->threadRunLoop();
+}
+
+template<typename Object, typename Function>
+void AsyncTask<Object, Function>::threadRunLoop()
+{
+ // This loop ratchets downward from most active to least active state. While
+ // we ratchet downward, any other thread may reset our state.
+
+ // We require any state change while we are sleeping to signal to our
+ // condition variable and wake us up.
+
+ while (1) {
+ if (m_state == State::Sleep) {
+ std::unique_lock<Mutex> lock(m_conditionMutex);
+ m_condition.wait(lock, [&]() { return m_state != State::Sleep; });
+ }
+
+ if (m_state == State::RunSoon) {
+ std::unique_lock<Mutex> lock(m_conditionMutex);
+ m_condition.wait_for(lock, asyncTaskSleepDuration, [&]() { return m_state != State::RunSoon; });
+ }
+
+ m_state = State::Sleep;
+ (m_object.*m_function)();
+ }
+}
+
+} // namespace bmalloc
+
+#endif // AsyncTask_h
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/AvailableMemory.cpp b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/AvailableMemory.cpp
new file mode 100644
index 0000000000..5674f8039a
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/AvailableMemory.cpp
@@ -0,0 +1,88 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "AvailableMemory.h"
+
+#include "Sizes.h"
+#include <mutex>
+#if BOS(DARWIN)
+#if BPLATFORM(IOS)
+#import <algorithm>
+#endif
+#import <dispatch/dispatch.h>
+#import <mach/host_info.h>
+#import <mach/mach.h>
+#import <mach/mach_error.h>
+#import <math.h>
+#elif BOS(UNIX)
+#include <unistd.h>
+#endif
+
+namespace bmalloc {
+
+static const size_t availableMemoryGuess = 512 * bmalloc::MB;
+
+static size_t computeAvailableMemory()
+{
+#if BPLATFORM(IOS_SIMULATOR)
+ // Pretend we have 512MB of memory to make cache sizes behave like on device.
+ return availableMemoryGuess;
+#elif BOS(DARWIN)
+ host_basic_info_data_t hostInfo;
+
+ mach_port_t host = mach_host_self();
+ mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
+ kern_return_t r = host_info(host, HOST_BASIC_INFO, (host_info_t)&hostInfo, &count);
+ mach_port_deallocate(mach_task_self(), host);
+ if (r != KERN_SUCCESS)
+ return availableMemoryGuess;
+
+ if (hostInfo.max_mem > std::numeric_limits<size_t>::max())
+ return std::numeric_limits<size_t>::max();
+
+ size_t sizeAccordingToKernel = static_cast<size_t>(hostInfo.max_mem);
+#if BPLATFORM(IOS)
+ sizeAccordingToKernel = std::min(sizeAccordingToKernel, 840 * bmalloc::MB);
+#endif
+ size_t multiple = 128 * bmalloc::MB;
+
+ // Round up the memory size to a multiple of 128MB because max_mem may not be exactly 512MB
+ // (for example) and we have code that depends on those boundaries.
+ return ((sizeAccordingToKernel + multiple - 1) / multiple) * multiple;
+#elif BOS(UNIX)
+ long pages = sysconf(_SC_PHYS_PAGES);
+ long pageSize = sysconf(_SC_PAGE_SIZE);
+ if (pages == -1 || pageSize == -1)
+ return availableMemoryGuess;
+ return pages * pageSize;
+#else
+ return availableMemoryGuess;
+#endif
+}
+
+size_t availableMemory()
+{
+ static size_t availableMemory;
+ static std::once_flag onceFlag;
+ std::call_once(onceFlag, [] {
+ availableMemory = computeAvailableMemory();
+ });
+ return availableMemory;
+}
+
+} // namespace bmalloc
diff --git a/weex_core/Source/android/jniprebuild/prebuild.sh b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/AvailableMemory.h
old mode 100755
new mode 100644
similarity index 63%
rename from weex_core/Source/android/jniprebuild/prebuild.sh
rename to weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/AvailableMemory.h
index 8eed73e47f..2946dd0b6c
--- a/weex_core/Source/android/jniprebuild/prebuild.sh
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/AvailableMemory.h
@@ -16,17 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
+#pragma once
+
+#include "BPlatform.h"
+#include "Sizes.h"
+
+namespace bmalloc {
+
+size_t availableMemory();
+
+}
-#!/bin/bash
-CURRENT_PATH=$(cd `dirname $0`; pwd)
-ROOT_WEEX_JAVA_PATH=$CURRENT_PATH"/../../../../android/sdk/src/main/java/"
-WEEX_OUTPUT_DIR=$CURRENT_PATH"/jniheader/"
-WEEX_GEN_FILE=$CURRENT_PATH"/jni_generator.py"
-while read line
-do
- file_name=${line##*/}
- jni_file_name=${file_name%.*}"_jni.h"
- input_file=$ROOT_WEEX_JAVA_PATH$line
- output_file=$WEEX_OUTPUT_DIR$jni_file_name
- python $WEEX_GEN_FILE $input_file $output_file
-done < $CURRENT_PATH"/jni_files"
\ No newline at end of file
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/BAssert.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/BAssert.h
new file mode 100644
index 0000000000..727772468c
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/BAssert.h
@@ -0,0 +1,102 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#pragma once
+
+#include "BPlatform.h"
+#include "Logging.h"
+
+#if BUSE(OS_LOG)
+#include <os/log.h>
+#endif
+
+#if defined(NDEBUG) && BOS(DARWIN)
+
+#if BCPU(X86_64) || BCPU(X86)
+#define BBreakpointTrap() __asm__ volatile ("int3")
+#elif BCPU(ARM_THUMB2)
+#define BBreakpointTrap() __asm__ volatile ("bkpt #0")
+#elif BCPU(ARM64)
+#define BBreakpointTrap() __asm__ volatile ("brk #0")
+#else
+#error "Unsupported CPU".
+#endif
+
+// Crash with a SIGTRAP i.e EXC_BREAKPOINT.
+// We are not using __builtin_trap because it is only guaranteed to abort, but not necessarily
+// trigger a SIGTRAP. Instead, we use inline asm to ensure that we trigger the SIGTRAP.
+#define BCRASH() do { \
+ BBreakpointTrap(); \
+ __builtin_unreachable(); \
+ } while (false)
+
+#else // not defined(NDEBUG) && BOS(DARWIN)
+
+#define BCRASH() do { \
+ *(int*)0xbbadbeef = 0; \
+} while (0);
+
+#endif // defined(NDEBUG) && BOS(DARWIN)
+
+#define BASSERT_IMPL(x) do { \
+ if (!(x)) \
+ BCRASH(); \
+} while (0);
+
+#define RELEASE_BASSERT(x) BASSERT_IMPL(x)
+
+#if BUSE(OS_LOG)
+#define BMALLOC_LOGGING_PREFIX "bmalloc: "
+#define BLOG_ERROR(format, ...) os_log_error(OS_LOG_DEFAULT, BMALLOC_LOGGING_PREFIX format, __VA_ARGS__)
+#else
+#define BLOG_ERROR(format, ...) bmalloc::reportAssertionFailureWithMessage(__FILE__, __LINE__, __PRETTY_FUNCTION__, format, __VA_ARGS__)
+#endif
+
+#if defined(NDEBUG)
+#define RELEASE_BASSERT_WITH_MESSAGE(x, format, ...) BASSERT_IMPL(x)
+#else
+#define RELEASE_BASSERT_WITH_MESSAGE(x, format, ...) do { \
+ if (!(x)) { \
+ BLOG_ERROR("ASSERTION FAILED: " #x " :: " format, ##__VA_ARGS__); \
+ BCRASH(); \
+ } \
+} while (0);
+#endif
+
+#define UNUSED(x) ((void)x)
+
+// ===== Release build =====
+
+#if defined(NDEBUG)
+
+#define BASSERT(x)
+
+#define IF_DEBUG(x)
+
+#endif // defined(NDEBUG)
+
+
+// ===== Debug build =====
+
+#if !defined(NDEBUG)
+
+#define BASSERT(x) BASSERT_IMPL(x)
+
+#define IF_DEBUG(x) (x)
+
+#endif // !defined(NDEBUG)
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/BPlatform.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/BPlatform.h
new file mode 100644
index 0000000000..38e4898bbc
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/BPlatform.h
@@ -0,0 +1,192 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#pragma once
+
+#ifdef __APPLE__
+#include <Availability.h>
+#include <AvailabilityMacros.h>
+#include <TargetConditionals.h>
+#endif
+
+#define BPLATFORM(PLATFORM) (defined BPLATFORM_##PLATFORM && BPLATFORM_##PLATFORM)
+#define BOS(OS) (defined BOS_##OS && BOS_##OS)
+
+#ifdef __APPLE__
+#define BOS_DARWIN 1
+#endif
+
+#ifdef __unix
+#define BOS_UNIX 1
+#endif
+
+#if BOS(DARWIN) && ((defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED) \
+ || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) \
+ || (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR))
+#define BPLATFORM_IOS 1
+#if (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR)
+#define BPLATFORM_IOS_SIMULATOR 1
+#endif
+#elif BOS(DARWIN) && defined(TARGET_OS_MAC) && TARGET_OS_MAC
+#define BPLATFORM_MAC 1
+#endif
+
+/* ==== Policy decision macros: these define policy choices for a particular port. ==== */
+
+/* BUSE() - use a particular third-party library or optional OS service */
+#define BUSE(FEATURE) (defined BUSE_##FEATURE && BUSE_##FEATURE)
+
+/* ==== Platform adaptation macros: these describe properties of the target environment. ==== */
+
+/* BCPU() - the target CPU architecture */
+#define BCPU(_FEATURE) (defined BCPU_##_FEATURE && BCPU_##_FEATURE)
+
+/* BCPU(X86) - i386 / x86 32-bit */
+#if defined(__i386__) \
+|| defined(i386) \
+|| defined(_M_IX86) \
+|| defined(_X86_) \
+|| defined(__THW_INTEL)
+#define BCPU_X86 1
+#endif
+
+/* BCPU(X86_64) - AMD64 / Intel64 / x86_64 64-bit */
+#if defined(__x86_64__) \
+|| defined(_M_X64)
+#define BCPU_X86_64 1
+#endif
+
+/* BCPU(ARM64) - Apple */
+#if (defined(__arm64__) && defined(__APPLE__)) || defined(__aarch64__)
+#define BCPU_ARM64 1
+#endif
+
+/* BCPU(ARM) - ARM, any version*/
+#define BARM_ARCH_AT_LEAST(N) (BCPU(ARM) && BARM_ARCH_VERSION >= N)
+
+#if defined(arm) \
+|| defined(__arm__) \
+|| defined(ARM) \
+|| defined(_ARM_)
+#define BCPU_ARM 1
+
+/* Set BARM_ARCH_VERSION */
+#if defined(__ARM_ARCH_4__) \
+|| defined(__ARM_ARCH_4T__) \
+|| defined(__MARM_ARMV4__)
+#define BARM_ARCH_VERSION 4
+
+#elif defined(__ARM_ARCH_5__) \
+|| defined(__ARM_ARCH_5T__) \
+|| defined(__MARM_ARMV5__)
+#define BARM_ARCH_VERSION 5
+
+#elif defined(__ARM_ARCH_5E__) \
+|| defined(__ARM_ARCH_5TE__) \
+|| defined(__ARM_ARCH_5TEJ__)
+#define BARM_ARCH_VERSION 5
+
+#elif defined(__ARM_ARCH_6__) \
+|| defined(__ARM_ARCH_6J__) \
+|| defined(__ARM_ARCH_6K__) \
+|| defined(__ARM_ARCH_6Z__) \
+|| defined(__ARM_ARCH_6ZK__) \
+|| defined(__ARM_ARCH_6T2__) \
+|| defined(__ARMV6__)
+#define BARM_ARCH_VERSION 6
+
+#elif defined(__ARM_ARCH_7A__) \
+|| defined(__ARM_ARCH_7K__) \
+|| defined(__ARM_ARCH_7R__) \
+|| defined(__ARM_ARCH_7S__)
+#define BARM_ARCH_VERSION 7
+
+#elif defined(__ARM_ARCH_8__)
+#define BARM_ARCH_VERSION 8
+
+/* MSVC sets _M_ARM */
+#elif defined(_M_ARM)
+#define BARM_ARCH_VERSION _M_ARM
+
+/* RVCT sets _TARGET_ARCH_ARM */
+#elif defined(__TARGET_ARCH_ARM)
+#define BARM_ARCH_VERSION __TARGET_ARCH_ARM
+
+#else
+#define WTF_ARM_ARCH_VERSION 0
+
+#endif
+
+/* Set BTHUMB_ARCH_VERSION */
+#if defined(__ARM_ARCH_4T__)
+#define BTHUMB_ARCH_VERSION 1
+
+#elif defined(__ARM_ARCH_5T__) \
+|| defined(__ARM_ARCH_5TE__) \
+|| defined(__ARM_ARCH_5TEJ__)
+#define BTHUMB_ARCH_VERSION 2
+
+#elif defined(__ARM_ARCH_6J__) \
+|| defined(__ARM_ARCH_6K__) \
+|| defined(__ARM_ARCH_6Z__) \
+|| defined(__ARM_ARCH_6ZK__) \
+|| defined(__ARM_ARCH_6M__)
+#define BTHUMB_ARCH_VERSION 3
+
+#elif defined(__ARM_ARCH_6T2__) \
+|| defined(__ARM_ARCH_7__) \
+|| defined(__ARM_ARCH_7A__) \
+|| defined(__ARM_ARCH_7K__) \
+|| defined(__ARM_ARCH_7M__) \
+|| defined(__ARM_ARCH_7R__) \
+|| defined(__ARM_ARCH_7S__)
+#define BTHUMB_ARCH_VERSION 4
+
+/* RVCT sets __TARGET_ARCH_THUMB */
+#elif defined(__TARGET_ARCH_THUMB)
+#define BTHUMB_ARCH_VERSION __TARGET_ARCH_THUMB
+
+#else
+#define BTHUMB_ARCH_VERSION 0
+#endif
+
+/* BCPU(ARM_TRADITIONAL) - Thumb2 is not available, only traditional ARM (v4 or greater) */
+/* BCPU(ARM_THUMB2) - Thumb2 instruction set is available */
+/* Only one of these will be defined. */
+#if !defined(BCPU_ARM_TRADITIONAL) && !defined(BCPU_ARM_THUMB2)
+# if defined(thumb2) || defined(__thumb2__) \
+|| ((defined(__thumb) || defined(__thumb__)) && BTHUMB_ARCH_VERSION == 4)
+# define BCPU_ARM_TRADITIONAL 0
+# define BCPU_ARM_THUMB2 1
+# elif BARM_ARCH_AT_LEAST(4)
+# define BCPU_ARM_TRADITIONAL 1
+# define BCPU_ARM_THUMB2 0
+# else
+# error "Not supported ARM architecture"
+# endif
+#elif BCPU(ARM_TRADITIONAL) && BCPU(ARM_THUMB2) /* Sanity Check */
+# error "Cannot use both of BCPU_ARM_TRADITIONAL and BCPU_ARM_THUMB2 platforms"
+#endif /* !defined(BCPU_ARM_TRADITIONAL) && !defined(BCPU_ARM_THUMB2) */
+
+#endif /* ARM */
+
+#define BATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments)))
+
+#if (BPLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) || (BPLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000)
+#define BUSE_OS_LOG 1
+#endif
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/BumpAllocator.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/BumpAllocator.h
new file mode 100644
index 0000000000..7cb0c9b58b
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/BumpAllocator.h
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef BumpAllocator_h
+#define BumpAllocator_h
+
+#include "BAssert.h"
+#include "BumpRange.h"
+#include "ObjectType.h"
+
+namespace bmalloc {
+
+// Helper object for allocating small objects.
+
+class BumpAllocator {
+public:
+ BumpAllocator();
+ void init(size_t);
+
+ size_t size() { return m_size; }
+
+ bool isNull() { return !m_ptr; }
+ void clear();
+
+ bool canAllocate() { return !!m_remaining; }
+ void* allocate();
+
+ void refill(const BumpRange&);
+
+private:
+ char* m_ptr;
+ unsigned m_size;
+ unsigned m_remaining;
+};
+
+inline BumpAllocator::BumpAllocator()
+ : m_ptr()
+ , m_size()
+ , m_remaining()
+{
+}
+
+inline void BumpAllocator::init(size_t size)
+{
+ m_ptr = nullptr;
+ m_size = size;
+ m_remaining = 0;
+}
+
+inline void* BumpAllocator::allocate()
+{
+ BASSERT(m_remaining);
+
+ --m_remaining;
+ char* result = m_ptr;
+ m_ptr += m_size;
+ return result;
+}
+
+inline void BumpAllocator::refill(const BumpRange& bumpRange)
+{
+ BASSERT(!canAllocate());
+ m_ptr = bumpRange.begin;
+ m_remaining = bumpRange.objectCount;
+ BASSERT(canAllocate());
+}
+
+inline void BumpAllocator::clear()
+{
+ m_ptr = nullptr;
+ m_remaining = 0;
+}
+
+} // namespace bmalloc
+
+#endif // BumpAllocator_h
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/BumpRange.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/BumpRange.h
new file mode 100644
index 0000000000..73a465b789
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/BumpRange.h
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef BumpRange_h
+#define BumpRange_h
+
+#include "FixedVector.h"
+#include "Range.h"
+#include "Sizes.h"
+
+namespace bmalloc {
+
+struct BumpRange {
+ char* begin;
+ unsigned short objectCount;
+};
+
+typedef FixedVector<BumpRange, bumpRangeCacheCapacity> BumpRangeCache;
+
+} // namespace bmalloc
+
+#endif // BumpRange_h
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Cache.cpp b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Cache.cpp
new file mode 100644
index 0000000000..1dd6f6589c
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Cache.cpp
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "Cache.h"
+#include "Heap.h"
+#include "Inline.h"
+#include "PerProcess.h"
+
+namespace bmalloc {
+
+void* Cache::operator new(size_t size)
+{
+ return vmAllocate(vmSize(size));
+}
+
+void Cache::operator delete(void* p, size_t size)
+{
+ vmDeallocate(p, vmSize(size));
+}
+
+void Cache::scavenge()
+{
+ Cache* cache = PerThread<Cache>::getFastCase();
+ if (!cache)
+ return;
+
+ cache->allocator().scavenge();
+ cache->deallocator().scavenge();
+}
+
+Cache::Cache()
+ : m_deallocator(PerProcess<Heap>::get())
+ , m_allocator(PerProcess<Heap>::get(), m_deallocator)
+{
+}
+
+NO_INLINE void* Cache::tryAllocateSlowCaseNullCache(size_t size)
+{
+ return PerThread<Cache>::getSlowCase()->allocator().tryAllocate(size);
+}
+
+NO_INLINE void* Cache::allocateSlowCaseNullCache(size_t size)
+{
+ return PerThread<Cache>::getSlowCase()->allocator().allocate(size);
+}
+
+NO_INLINE void* Cache::allocateSlowCaseNullCache(size_t alignment, size_t size)
+{
+ return PerThread<Cache>::getSlowCase()->allocator().allocate(alignment, size);
+}
+
+NO_INLINE void Cache::deallocateSlowCaseNullCache(void* object)
+{
+ PerThread<Cache>::getSlowCase()->deallocator().deallocate(object);
+}
+
+NO_INLINE void* Cache::reallocateSlowCaseNullCache(void* object, size_t newSize)
+{
+ return PerThread<Cache>::getSlowCase()->allocator().reallocate(object, newSize);
+}
+
+} // namespace bmalloc
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Cache.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Cache.h
new file mode 100644
index 0000000000..ea1ace1c1c
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Cache.h
@@ -0,0 +1,110 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef Cache_h
+#define Cache_h
+
+#include "Allocator.h"
+#include "Deallocator.h"
+#include "PerThread.h"
+
+namespace bmalloc {
+
+// Per-thread allocation / deallocation cache, backed by a per-process Heap.
+
+class Cache {
+public:
+ void* operator new(size_t);
+ void operator delete(void*, size_t);
+
+ static void* tryAllocate(size_t);
+ static void* allocate(size_t);
+ static void* tryAllocate(size_t alignment, size_t);
+ static void* allocate(size_t alignment, size_t);
+ static void deallocate(void*);
+ static void* reallocate(void*, size_t);
+
+ static void scavenge();
+
+ Cache();
+
+ Allocator& allocator() { return m_allocator; }
+ Deallocator& deallocator() { return m_deallocator; }
+
+private:
+ static void* tryAllocateSlowCaseNullCache(size_t);
+ static void* allocateSlowCaseNullCache(size_t);
+ static void* allocateSlowCaseNullCache(size_t alignment, size_t);
+ static void deallocateSlowCaseNullCache(void*);
+ static void* reallocateSlowCaseNullCache(void*, size_t);
+
+ Deallocator m_deallocator;
+ Allocator m_allocator;
+};
+
+inline void* Cache::tryAllocate(size_t size)
+{
+ Cache* cache = PerThread<Cache>::getFastCase();
+ if (!cache)
+ return tryAllocateSlowCaseNullCache(size);
+ return cache->allocator().tryAllocate(size);
+}
+
+inline void* Cache::allocate(size_t size)
+{
+ Cache* cache = PerThread<Cache>::getFastCase();
+ if (!cache)
+ return allocateSlowCaseNullCache(size);
+ return cache->allocator().allocate(size);
+}
+
+inline void* Cache::tryAllocate(size_t alignment, size_t size)
+{
+ Cache* cache = PerThread<Cache>::getFastCase();
+ if (!cache)
+ return allocateSlowCaseNullCache(alignment, size);
+ return cache->allocator().tryAllocate(alignment, size);
+}
+
+inline void* Cache::allocate(size_t alignment, size_t size)
+{
+ Cache* cache = PerThread<Cache>::getFastCase();
+ if (!cache)
+ return allocateSlowCaseNullCache(alignment, size);
+ return cache->allocator().allocate(alignment, size);
+}
+
+inline void Cache::deallocate(void* object)
+{
+ Cache* cache = PerThread<Cache>::getFastCase();
+ if (!cache)
+ return deallocateSlowCaseNullCache(object);
+ return cache->deallocator().deallocate(object);
+}
+
+inline void* Cache::reallocate(void* object, size_t newSize)
+{
+ Cache* cache = PerThread<Cache>::getFastCase();
+ if (!cache)
+ return reallocateSlowCaseNullCache(object, newSize);
+ return cache->allocator().reallocate(object, newSize);
+}
+
+} // namespace bmalloc
+
+#endif // Cache_h
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Chunk.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Chunk.h
new file mode 100644
index 0000000000..3208277484
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Chunk.h
@@ -0,0 +1,146 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef Chunk_h
+#define Chunk_h
+
+#include "Object.h"
+#include "Sizes.h"
+#include "SmallLine.h"
+#include "SmallPage.h"
+#include "VMAllocate.h"
+#include <array>
+
+namespace bmalloc {
+
+class Chunk {
+public:
+ static Chunk* get(void*);
+
+ Chunk(std::lock_guard<StaticMutex>&);
+
+ size_t offset(void*);
+
+ char* address(size_t offset);
+ SmallPage* page(size_t offset);
+ SmallLine* line(size_t offset);
+
+ char* bytes() { return reinterpret_cast<char*>(this); }
+ SmallLine* lines() { return &m_lines[0]; }
+ SmallPage* pages() { return &m_pages[0]; }
+
+private:
+ std::array<SmallLine, chunkSize / smallLineSize> m_lines;
+ std::array<SmallPage, chunkSize / smallPageSize> m_pages;
+};
+
+struct ChunkHash {
+ static unsigned hash(Chunk* key)
+ {
+ return static_cast<unsigned>(
+ reinterpret_cast<uintptr_t>(key) / chunkSize);
+ }
+};
+
+inline Chunk::Chunk(std::lock_guard<StaticMutex>&)
+{
+}
+
+inline Chunk* Chunk::get(void* address)
+{
+ return static_cast<Chunk*>(mask(address, chunkMask));
+}
+
+inline size_t Chunk::offset(void* address)
+{
+ BASSERT(address >= this);
+ BASSERT(address < bytes() + chunkSize);
+ return static_cast<char*>(address) - bytes();
+}
+
+inline char* Chunk::address(size_t offset)
+{
+ return bytes() + offset;
+}
+
+inline SmallPage* Chunk::page(size_t offset)
+{
+ size_t pageNumber = offset / smallPageSize;
+ SmallPage* page = &m_pages[pageNumber];
+ return page - page->slide();
+}
+
+inline SmallLine* Chunk::line(size_t offset)
+{
+ size_t lineNumber = offset / smallLineSize;
+ return &m_lines[lineNumber];
+}
+
+inline char* SmallLine::begin()
+{
+ Chunk* chunk = Chunk::get(this);
+ size_t lineNumber = this - chunk->lines();
+ size_t offset = lineNumber * smallLineSize;
+ return &reinterpret_cast<char*>(chunk)[offset];
+}
+
+inline char* SmallLine::end()
+{
+ return begin() + smallLineSize;
+}
+
+inline SmallLine* SmallPage::begin()
+{
+ BASSERT(!m_slide);
+ Chunk* chunk = Chunk::get(this);
+ size_t pageNumber = this - chunk->pages();
+ size_t lineNumber = pageNumber * smallPageLineCount;
+ return &chunk->lines()[lineNumber];
+}
+
+inline Object::Object(void* object)
+ : m_chunk(Chunk::get(object))
+ , m_offset(m_chunk->offset(object))
+{
+}
+
+inline Object::Object(Chunk* chunk, void* object)
+ : m_chunk(chunk)
+ , m_offset(m_chunk->offset(object))
+{
+ BASSERT(chunk == Chunk::get(object));
+}
+
+inline char* Object::address()
+{
+ return m_chunk->address(m_offset);
+}
+
+inline SmallLine* Object::line()
+{
+ return m_chunk->line(m_offset);
+}
+
+inline SmallPage* Object::page()
+{
+ return m_chunk->page(m_offset);
+}
+
+}; // namespace bmalloc
+
+#endif // Chunk
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Deallocator.cpp b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Deallocator.cpp
new file mode 100644
index 0000000000..f6801f2c2a
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Deallocator.cpp
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "BAssert.h"
+#include "Chunk.h"
+#include "Deallocator.h"
+#include "DebugHeap.h"
+#include "Heap.h"
+#include "Inline.h"
+#include "Object.h"
+#include "PerProcess.h"
+#include <algorithm>
+#include <cstdlib>
+#include <sys/mman.h>
+
+using namespace std;
+
+namespace bmalloc {
+
+Deallocator::Deallocator(Heap* heap)
+ : m_debugHeap(heap->debugHeap())
+{
+ if (m_debugHeap) {
+ // Fill the object log in order to disable the fast path.
+ while (m_objectLog.size() != m_objectLog.capacity())
+ m_objectLog.push(nullptr);
+ }
+}
+
+Deallocator::~Deallocator()
+{
+ scavenge();
+}
+
+void Deallocator::scavenge()
+{
+ if (m_debugHeap)
+ return;
+
+ processObjectLog();
+}
+
+void Deallocator::processObjectLog(std::lock_guard<StaticMutex>& lock)
+{
+ Heap* heap = PerProcess<Heap>::getFastCase();
+
+ for (Object object : m_objectLog)
+ heap->derefSmallLine(lock, object);
+
+ m_objectLog.clear();
+}
+
+void Deallocator::processObjectLog()
+{
+ std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
+ processObjectLog(lock);
+}
+
+void Deallocator::deallocateSlowCase(void* object)
+{
+ if (m_debugHeap)
+ return m_debugHeap->free(object);
+
+ if (!object)
+ return;
+
+ std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
+ if (PerProcess<Heap>::getFastCase()->isLarge(lock, object)) {
+ PerProcess<Heap>::getFastCase()->deallocateLarge(lock, object);
+ return;
+ }
+
+ if (m_objectLog.size() == m_objectLog.capacity())
+ processObjectLog(lock);
+
+ m_objectLog.push(object);
+}
+
+} // namespace bmalloc
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Deallocator.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Deallocator.h
new file mode 100644
index 0000000000..aaf537d3e4
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Deallocator.h
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef Deallocator_h
+#define Deallocator_h
+
+#include "FixedVector.h"
+#include <mutex>
+
+namespace bmalloc {
+
+class DebugHeap;
+class Heap;
+class StaticMutex;
+
+// Per-cache object deallocator.
+
+class Deallocator {
+public:
+ Deallocator(Heap*);
+ ~Deallocator();
+
+ void deallocate(void*);
+ void scavenge();
+
+ void processObjectLog();
+ void processObjectLog(std::lock_guard<StaticMutex>&);
+
+private:
+ bool deallocateFastCase(void*);
+ void deallocateSlowCase(void*);
+
+ FixedVector<void*, deallocatorLogCapacity> m_objectLog;
+ DebugHeap* m_debugHeap;
+};
+
+inline bool Deallocator::deallocateFastCase(void* object)
+{
+ BASSERT(mightBeLarge(nullptr));
+ if (mightBeLarge(object))
+ return false;
+
+ if (m_objectLog.size() == m_objectLog.capacity())
+ return false;
+
+ m_objectLog.push(object);
+ return true;
+}
+
+inline void Deallocator::deallocate(void* object)
+{
+ if (!deallocateFastCase(object))
+ deallocateSlowCase(object);
+}
+
+} // namespace bmalloc
+
+#endif // Deallocator_h
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/DebugHeap.cpp b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/DebugHeap.cpp
new file mode 100644
index 0000000000..54f850965e
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/DebugHeap.cpp
@@ -0,0 +1,104 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "DebugHeap.h"
+#include "BAssert.h"
+#include "BPlatform.h"
+#include <cstdlib>
+#include <thread>
+
+namespace bmalloc {
+
+#if BOS(DARWIN)
+
+DebugHeap::DebugHeap(std::lock_guard<StaticMutex>&)
+ : m_zone(malloc_create_zone(0, 0))
+{
+ malloc_set_zone_name(m_zone, "WebKit Using System Malloc");
+}
+
+void* DebugHeap::malloc(size_t size)
+{
+ void* result = malloc_zone_malloc(m_zone, size);
+ if (!result)
+ BCRASH();
+ return result;
+}
+
+void* DebugHeap::memalign(size_t alignment, size_t size, bool crashOnFailure)
+{
+ void* result = malloc_zone_memalign(m_zone, alignment, size);
+ if (!result && crashOnFailure)
+ BCRASH();
+ return result;
+}
+
+void* DebugHeap::realloc(void* object, size_t size)
+{
+ void* result = malloc_zone_realloc(m_zone, object, size);
+ if (!result)
+ BCRASH();
+ return result;
+}
+
+void DebugHeap::free(void* object)
+{
+ malloc_zone_free(m_zone, object);
+}
+
+#else
+
+DebugHeap::DebugHeap(std::lock_guard<StaticMutex>&)
+{
+}
+
+void* DebugHeap::malloc(size_t size)
+{
+ void* result = ::malloc(size);
+ if (!result)
+ BCRASH();
+ return result;
+}
+
+void* DebugHeap::memalign(size_t alignment, size_t size, bool crashOnFailure)
+{
+ void* result;
+ if (posix_memalign(&result, alignment, size)) {
+ if (crashOnFailure)
+ BCRASH();
+ return nullptr;
+ }
+ return result;
+}
+
+void* DebugHeap::realloc(void* object, size_t size)
+{
+ void* result = ::realloc(object, size);
+ if (!result)
+ BCRASH();
+ return result;
+}
+
+void DebugHeap::free(void* object)
+{
+ ::free(object);
+}
+
+#endif
+
+} // namespace bmalloc
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/DebugHeap.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/DebugHeap.h
new file mode 100644
index 0000000000..c02345ff84
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/DebugHeap.h
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#pragma once
+
+#include "StaticMutex.h"
+#include <mutex>
+#if BOS(DARWIN)
+#include <malloc/malloc.h>
+#endif
+
+namespace bmalloc {
+
+class DebugHeap {
+public:
+ DebugHeap(std::lock_guard<StaticMutex>&);
+
+ void* malloc(size_t);
+ void* memalign(size_t alignment, size_t, bool crashOnFailure);
+ void* realloc(void*, size_t);
+ void free(void*);
+
+private:
+#if BOS(DARWIN)
+ malloc_zone_t* m_zone;
+#endif
+};
+
+} // namespace bmalloc
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Environment.cpp b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Environment.cpp
new file mode 100644
index 0000000000..8bae09966c
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Environment.cpp
@@ -0,0 +1,119 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "BPlatform.h"
+#include "Environment.h"
+#include <cstdlib>
+#include <cstring>
+#if BOS(DARWIN)
+#include <mach-o/dyld.h>
+#elif BOS(UNIX)
+#include <dlfcn.h>
+#endif
+
+namespace bmalloc {
+
+static bool isMallocEnvironmentVariableSet()
+{
+ const char* list[] = {
+ "Malloc",
+ "MallocLogFile",
+ "MallocGuardEdges",
+ "MallocDoNotProtectPrelude",
+ "MallocDoNotProtectPostlude",
+ "MallocStackLogging",
+ "MallocStackLoggingNoCompact",
+ "MallocStackLoggingDirectory",
+ "MallocScribble",
+ "MallocCheckHeapStart",
+ "MallocCheckHeapEach",
+ "MallocCheckHeapSleep",
+ "MallocCheckHeapAbort",
+ "MallocErrorAbort",
+ "MallocCorruptionAbort",
+ "MallocHelp"
+ };
+ size_t size = sizeof(list) / sizeof(const char*);
+
+ for (size_t i = 0; i < size; ++i) {
+ if (getenv(list[i]))
+ return true;
+ }
+
+ return false;
+}
+
+static bool isLibgmallocEnabled()
+{
+ char* variable = getenv("DYLD_INSERT_LIBRARIES");
+ if (!variable)
+ return false;
+ if (!strstr(variable, "libgmalloc"))
+ return false;
+ return true;
+}
+
+static bool isSanitizerEnabled()
+{
+#if BOS(DARWIN)
+ static const char sanitizerPrefix[] = "/libclang_rt.";
+ static const char asanName[] = "asan_";
+ static const char tsanName[] = "tsan_";
+ uint32_t imageCount = _dyld_image_count();
+ for (uint32_t i = 0; i < imageCount; ++i) {
+ const char* imageName = _dyld_get_image_name(i);
+ if (!imageName)
+ continue;
+ if (const char* s = strstr(imageName, sanitizerPrefix)) {
+ const char* sanitizerName = s + sizeof(sanitizerPrefix) - 1;
+ if (!strncmp(sanitizerName, asanName, sizeof(asanName) - 1))
+ return true;
+ if (!strncmp(sanitizerName, tsanName, sizeof(tsanName) - 1))
+ return true;
+ }
+ }
+ return false;
+#elif BOS(UNIX)
+ void* handle = dlopen(nullptr, RTLD_NOW);
+ if (!handle)
+ return false;
+ bool result = !!dlsym(handle, "__asan_init") || !!dlsym(handle, "__tsan_init");
+ dlclose(handle);
+ return result;
+#else
+ return false;
+#endif
+}
+
+Environment::Environment()
+ : m_isDebugHeapEnabled(computeIsDebugHeapEnabled())
+{
+}
+
+bool Environment::computeIsDebugHeapEnabled()
+{
+ if (isMallocEnvironmentVariableSet())
+ return true;
+ if (isLibgmallocEnabled())
+ return true;
+ if (isSanitizerEnabled())
+ return true;
+ return false;
+}
+
+} // namespace bmalloc
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Environment.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Environment.h
new file mode 100644
index 0000000000..cc43f0e867
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Environment.h
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef Environment_h
+#define Environment_h
+
+namespace bmalloc {
+
+class Environment {
+public:
+ Environment();
+
+ bool isDebugHeapEnabled() { return m_isDebugHeapEnabled; }
+
+private:
+ bool computeIsDebugHeapEnabled();
+
+ bool m_isDebugHeapEnabled;
+};
+
+} // namespace bmalloc
+
+#endif // Environment_h
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/FixedVector.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/FixedVector.h
new file mode 100644
index 0000000000..50088f9264
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/FixedVector.h
@@ -0,0 +1,112 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef FixedVector_h
+#define FixedVector_h
+
+#include "BAssert.h"
+#include <array>
+#include <cstddef>
+#include <type_traits>
+
+namespace bmalloc {
+
+// A replacement for std::vector that uses a fixed-sized inline backing store.
+
+template<typename T, size_t Capacity>
+class FixedVector {
+ static_assert(std::is_trivially_destructible<T>::value, "FixedVector must have a trivial destructor.");
+public:
+ FixedVector(const FixedVector&) = delete;
+ FixedVector& operator=(const FixedVector&) = delete;
+
+ FixedVector();
+
+ const T* begin() const { return &m_buffer[0]; }
+ const T* end() const { return begin() + size(); }
+
+ size_t size() const { return m_size; }
+ size_t capacity() const { return Capacity; }
+
+ T& operator[](size_t);
+
+ void push(const T&);
+ void push(const T*, const T*);
+ T pop();
+
+ void shrink(T*);
+ void shrink(size_t);
+
+ void clear() { shrink(static_cast<size_t>(0)); }
+ bool isEmpty() { return !m_size; }
+
+private:
+ size_t m_size;
+ std::array<T, Capacity> m_buffer;
+};
+
+template<typename T, size_t Capacity>
+inline FixedVector<T, Capacity>::FixedVector()
+ : m_size(0)
+{
+}
+
+template<typename T, size_t Capacity>
+inline T& FixedVector<T, Capacity>::operator[](size_t i)
+{
+ BASSERT(i < m_size);
+ return m_buffer[i];
+}
+
+template<typename T, size_t Capacity>
+inline void FixedVector<T, Capacity>::push(const T& value)
+{
+ BASSERT(m_size < Capacity);
+ m_buffer[m_size++] = value;
+}
+
+template<typename T, size_t Capacity>
+inline void FixedVector<T, Capacity>::push(const T* begin, const T* end)
+{
+ for (const T* it = begin; it != end; ++it)
+ push(*it);
+}
+
+template<typename T, size_t Capacity>
+inline T FixedVector<T, Capacity>::pop()
+{
+ BASSERT(m_size);
+ return m_buffer[--m_size];
+}
+
+template<typename T, size_t Capacity>
+inline void FixedVector<T, Capacity>::shrink(size_t size)
+{
+ BASSERT(size <= m_size);
+ m_size = size;
+}
+
+template<typename T, size_t Capacity>
+inline void FixedVector<T, Capacity>::shrink(T* end)
+{
+ shrink(end - begin());
+}
+
+} // namespace bmalloc
+
+#endif // FixedVector_h
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Heap.cpp b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Heap.cpp
new file mode 100644
index 0000000000..c77200340c
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Heap.cpp
@@ -0,0 +1,487 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "Heap.h"
+
+#if BPLATFORM(IOS)
+#include "AvailableMemory.h"
+#endif
+#include "BumpAllocator.h"
+#include "Chunk.h"
+#include "DebugHeap.h"
+#include "PerProcess.h"
+#include "SmallLine.h"
+#include "SmallPage.h"
+#include <thread>
+
+#if BOS(DARWIN)
+#include "bmalloc.h"
+#if BPLATFORM(IOS)
+#import <mach/host_info.h>
+#import <mach/mach.h>
+#import <mach/mach_error.h>
+#endif
+#endif
+
+namespace bmalloc {
+
+Heap::Heap(std::lock_guard<StaticMutex>&)
+ : m_vmPageSizePhysical(vmPageSizePhysical())
+ , m_scavenger(*this, &Heap::concurrentScavenge)
+ , m_debugHeap(nullptr)
+#if BPLATFORM(IOS)
+ , m_maxAvailableMemory(availableMemory())
+#endif
+{
+ RELEASE_BASSERT(vmPageSizePhysical() >= smallPageSize);
+ RELEASE_BASSERT(vmPageSize() >= vmPageSizePhysical());
+
+ initializeLineMetadata();
+ initializePageMetadata();
+
+ if (m_environment.isDebugHeapEnabled())
+ m_debugHeap = PerProcess<DebugHeap>::get();
+
+#if BOS(DARWIN)
+ auto queue = dispatch_queue_create("WebKit Malloc Memory Pressure Handler", DISPATCH_QUEUE_SERIAL);
+ m_pressureHandlerDispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, DISPATCH_MEMORYPRESSURE_CRITICAL, queue);
+ dispatch_source_set_event_handler(m_pressureHandlerDispatchSource, ^{
+ std::unique_lock<StaticMutex> lock(PerProcess<Heap>::mutex());
+ scavenge(lock);
+ });
+ dispatch_resume(m_pressureHandlerDispatchSource);
+ dispatch_release(queue);
+#endif
+}
+
+void Heap::initializeLineMetadata()
+{
+ size_t sizeClassCount = bmalloc::sizeClass(smallLineSize);
+ size_t smallLineCount = m_vmPageSizePhysical / smallLineSize;
+ m_smallLineMetadata.grow(sizeClassCount * smallLineCount);
+
+ for (size_t sizeClass = 0; sizeClass < sizeClassCount; ++sizeClass) {
+ size_t size = objectSize(sizeClass);
+ LineMetadata* pageMetadata = &m_smallLineMetadata[sizeClass * smallLineCount];
+
+ size_t object = 0;
+ size_t line = 0;
+ while (object < m_vmPageSizePhysical) {
+ line = object / smallLineSize;
+ size_t leftover = object % smallLineSize;
+
+ size_t objectCount;
+ size_t remainder;
+ divideRoundingUp(smallLineSize - leftover, size, objectCount, remainder);
+
+ pageMetadata[line] = { static_cast<unsigned char>(leftover), static_cast<unsigned char>(objectCount) };
+
+ object += objectCount * size;
+ }
+
+ // Don't allow the last object in a page to escape the page.
+ if (object > m_vmPageSizePhysical) {
+ BASSERT(pageMetadata[line].objectCount);
+ --pageMetadata[line].objectCount;
+ }
+ }
+}
+
+void Heap::initializePageMetadata()
+{
+ auto computePageSize = [&](size_t sizeClass) {
+ size_t size = objectSize(sizeClass);
+ if (sizeClass < bmalloc::sizeClass(smallLineSize))
+ return m_vmPageSizePhysical;
+
+ for (size_t pageSize = m_vmPageSizePhysical;
+ pageSize < pageSizeMax;
+ pageSize += m_vmPageSizePhysical) {
+ RELEASE_BASSERT(pageSize <= chunkSize / 2);
+ size_t waste = pageSize % size;
+ if (waste <= pageSize / pageSizeWasteFactor)
+ return pageSize;
+ }
+
+ return pageSizeMax;
+ };
+
+ for (size_t i = 0; i < sizeClassCount; ++i)
+ m_pageClasses[i] = (computePageSize(i) - 1) / smallPageSize;
+}
+
+#if BPLATFORM(IOS)
+void Heap::updateMemoryInUseParameters()
+{
+ task_vm_info_data_t vmInfo;
+ mach_msg_type_number_t vmSize = TASK_VM_INFO_COUNT;
+
+ if (KERN_SUCCESS != task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)(&vmInfo), &vmSize))
+ m_memoryFootprint = 0;
+ else
+ m_memoryFootprint = static_cast<size_t>(vmInfo.phys_footprint);
+
+ double percentInUse = static_cast<double>(m_memoryFootprint) / static_cast<double>(m_maxAvailableMemory);
+ m_percentAvailableMemoryInUse = std::min(percentInUse, 1.0);
+}
+#endif
+
+void Heap::concurrentScavenge()
+{
+ std::unique_lock<StaticMutex> lock(PerProcess<Heap>::mutex());
+
+#if BOS(DARWIN)
+ pthread_set_qos_class_self_np(m_requestedScavengerThreadQOSClass, 0);
+#endif
+
+ if (m_isGrowing && !isUnderMemoryPressure()) {
+ m_isGrowing = false;
+ m_scavenger.runSoon();
+ return;
+ }
+
+ scavenge(lock);
+}
+
+void Heap::scavenge(std::unique_lock<StaticMutex>& lock)
+{
+ scavengeSmallPages(lock);
+ scavengeLargeObjects(lock);
+}
+
+void Heap::scavengeSmallPages(std::unique_lock<StaticMutex>& lock)
+{
+ for (size_t pageClass = 0; pageClass < pageClassCount; pageClass++) {
+ auto& smallPages = m_smallPages[pageClass];
+
+ while (!smallPages.isEmpty()) {
+ SmallPage* page = smallPages.pop();
+ m_vmHeap.deallocateSmallPage(lock, pageClass, page);
+ }
+ }
+}
+
+void Heap::scavengeLargeObjects(std::unique_lock<StaticMutex>& lock)
+{
+ auto& ranges = m_largeFree.ranges();
+ for (size_t i = ranges.size(); i-- > 0; i = std::min(i, ranges.size())) {
+ auto range = ranges.pop(i);
+
+ lock.unlock();
+ vmDeallocatePhysicalPagesSloppy(range.begin(), range.size());
+ lock.lock();
+
+ range.setPhysicalSize(0);
+ ranges.push(range);
+ }
+}
+
+void Heap::scheduleScavengerIfUnderMemoryPressure(size_t bytes)
+{
+ m_scavengerBytes += bytes;
+ if (m_scavengerBytes < scavengerBytesPerMemoryPressureCheck)
+ return;
+
+ m_scavengerBytes = 0;
+
+ if (m_scavenger.willRun())
+ return;
+
+ if (!isUnderMemoryPressure())
+ return;
+
+ m_isGrowing = false;
+ m_scavenger.run();
+}
+
+void Heap::scheduleScavenger(size_t bytes)
+{
+ scheduleScavengerIfUnderMemoryPressure(bytes);
+
+ if (m_scavenger.willRunSoon())
+ return;
+
+ m_isGrowing = false;
+ m_scavenger.runSoon();
+}
+
+SmallPage* Heap::allocateSmallPage(std::lock_guard<StaticMutex>& lock, size_t sizeClass)
+{
+ if (!m_smallPagesWithFreeLines[sizeClass].isEmpty())
+ return m_smallPagesWithFreeLines[sizeClass].popFront();
+
+ m_isGrowing = true;
+
+ SmallPage* page = [&]() {
+ size_t pageClass = m_pageClasses[sizeClass];
+ if (!m_smallPages[pageClass].isEmpty())
+ return m_smallPages[pageClass].pop();
+
+ scheduleScavengerIfUnderMemoryPressure(pageSize(pageClass));
+
+ SmallPage* page = m_vmHeap.allocateSmallPage(lock, pageClass);
+ m_objectTypes.set(Chunk::get(page), ObjectType::Small);
+ return page;
+ }();
+
+ page->setSizeClass(sizeClass);
+ return page;
+}
+
+void Heap::deallocateSmallLine(std::lock_guard<StaticMutex>& lock, Object object)
+{
+ BASSERT(!object.line()->refCount(lock));
+ SmallPage* page = object.page();
+ page->deref(lock);
+
+ if (!page->hasFreeLines(lock)) {
+ page->setHasFreeLines(lock, true);
+ m_smallPagesWithFreeLines[page->sizeClass()].push(page);
+ }
+
+ if (page->refCount(lock))
+ return;
+
+ size_t sizeClass = page->sizeClass();
+ size_t pageClass = m_pageClasses[sizeClass];
+
+ m_smallPagesWithFreeLines[sizeClass].remove(page);
+ m_smallPages[pageClass].push(page);
+
+ scheduleScavenger(pageSize(pageClass));
+}
+
+void Heap::allocateSmallBumpRangesByMetadata(
+ std::lock_guard<StaticMutex>& lock, size_t sizeClass,
+ BumpAllocator& allocator, BumpRangeCache& rangeCache)
+{
+ SmallPage* page = allocateSmallPage(lock, sizeClass);
+ SmallLine* lines = page->begin();
+ BASSERT(page->hasFreeLines(lock));
+ size_t smallLineCount = m_vmPageSizePhysical / smallLineSize;
+ LineMetadata* pageMetadata = &m_smallLineMetadata[sizeClass * smallLineCount];
+
+ auto findSmallBumpRange = [&](size_t& lineNumber) {
+ for ( ; lineNumber < smallLineCount; ++lineNumber) {
+ if (!lines[lineNumber].refCount(lock)) {
+ if (pageMetadata[lineNumber].objectCount)
+ return true;
+ }
+ }
+ return false;
+ };
+
+ auto allocateSmallBumpRange = [&](size_t& lineNumber) -> BumpRange {
+ char* begin = lines[lineNumber].begin() + pageMetadata[lineNumber].startOffset;
+ unsigned short objectCount = 0;
+
+ for ( ; lineNumber < smallLineCount; ++lineNumber) {
+ if (lines[lineNumber].refCount(lock))
+ break;
+
+ if (!pageMetadata[lineNumber].objectCount)
+ continue;
+
+ objectCount += pageMetadata[lineNumber].objectCount;
+ lines[lineNumber].ref(lock, pageMetadata[lineNumber].objectCount);
+ page->ref(lock);
+ }
+ return { begin, objectCount };
+ };
+
+ size_t lineNumber = 0;
+ for (;;) {
+ if (!findSmallBumpRange(lineNumber)) {
+ page->setHasFreeLines(lock, false);
+ BASSERT(allocator.canAllocate());
+ return;
+ }
+
+ // In a fragmented page, some free ranges might not fit in the cache.
+ if (rangeCache.size() == rangeCache.capacity()) {
+ m_smallPagesWithFreeLines[sizeClass].push(page);
+ BASSERT(allocator.canAllocate());
+ return;
+ }
+
+ BumpRange bumpRange = allocateSmallBumpRange(lineNumber);
+ if (allocator.canAllocate())
+ rangeCache.push(bumpRange);
+ else
+ allocator.refill(bumpRange);
+ }
+}
+
+void Heap::allocateSmallBumpRangesByObject(
+ std::lock_guard<StaticMutex>& lock, size_t sizeClass,
+ BumpAllocator& allocator, BumpRangeCache& rangeCache)
+{
+ size_t size = allocator.size();
+ SmallPage* page = allocateSmallPage(lock, sizeClass);
+ BASSERT(page->hasFreeLines(lock));
+
+ auto findSmallBumpRange = [&](Object& it, Object& end) {
+ for ( ; it + size <= end; it = it + size) {
+ if (!it.line()->refCount(lock))
+ return true;
+ }
+ return false;
+ };
+
+ auto allocateSmallBumpRange = [&](Object& it, Object& end) -> BumpRange {
+ char* begin = it.address();
+ unsigned short objectCount = 0;
+ for ( ; it + size <= end; it = it + size) {
+ if (it.line()->refCount(lock))
+ break;
+
+ ++objectCount;
+ it.line()->ref(lock);
+ it.page()->ref(lock);
+ }
+ return { begin, objectCount };
+ };
+
+ Object it(page->begin()->begin());
+ Object end(it + pageSize(m_pageClasses[sizeClass]));
+ for (;;) {
+ if (!findSmallBumpRange(it, end)) {
+ page->setHasFreeLines(lock, false);
+ BASSERT(allocator.canAllocate());
+ return;
+ }
+
+ // In a fragmented page, some free ranges might not fit in the cache.
+ if (rangeCache.size() == rangeCache.capacity()) {
+ m_smallPagesWithFreeLines[sizeClass].push(page);
+ BASSERT(allocator.canAllocate());
+ return;
+ }
+
+ BumpRange bumpRange = allocateSmallBumpRange(it, end);
+ if (allocator.canAllocate())
+ rangeCache.push(bumpRange);
+ else
+ allocator.refill(bumpRange);
+ }
+}
+
+LargeRange Heap::splitAndAllocate(LargeRange& range, size_t alignment, size_t size)
+{
+ LargeRange prev;
+ LargeRange next;
+
+ size_t alignmentMask = alignment - 1;
+ if (test(range.begin(), alignmentMask)) {
+ size_t prefixSize = roundUpToMultipleOf(alignment, range.begin()) - range.begin();
+ std::pair<LargeRange, LargeRange> pair = range.split(prefixSize);
+ prev = pair.first;
+ range = pair.second;
+ }
+
+ if (range.size() - size > size / pageSizeWasteFactor) {
+ std::pair<LargeRange, LargeRange> pair = range.split(size);
+ range = pair.first;
+ next = pair.second;
+ }
+
+ if (range.physicalSize() < range.size()) {
+ scheduleScavengerIfUnderMemoryPressure(range.size());
+
+ vmAllocatePhysicalPagesSloppy(range.begin() + range.physicalSize(), range.size() - range.physicalSize());
+ range.setPhysicalSize(range.size());
+ }
+
+ if (prev)
+ m_largeFree.add(prev);
+
+ if (next)
+ m_largeFree.add(next);
+
+ m_objectTypes.set(Chunk::get(range.begin()), ObjectType::Large);
+
+ m_largeAllocated.set(range.begin(), range.size());
+ return range;
+}
+
+void* Heap::tryAllocateLarge(std::lock_guard<StaticMutex>& lock, size_t alignment, size_t size)
+{
+ BASSERT(isPowerOfTwo(alignment));
+
+ m_isGrowing = true;
+
+ size_t roundedSize = size ? roundUpToMultipleOf(largeAlignment, size) : largeAlignment;
+ if (roundedSize < size) // Check for overflow
+ return nullptr;
+ size = roundedSize;
+
+ size_t roundedAlignment = roundUpToMultipleOf<largeAlignment>(alignment);
+ if (roundedAlignment < alignment) // Check for overflow
+ return nullptr;
+ alignment = roundedAlignment;
+
+ LargeRange range = m_largeFree.remove(alignment, size);
+ if (!range) {
+ range = m_vmHeap.tryAllocateLargeChunk(lock, alignment, size);
+ if (!range)
+ return nullptr;
+
+ m_largeFree.add(range);
+ range = m_largeFree.remove(alignment, size);
+ }
+
+ return splitAndAllocate(range, alignment, size).begin();
+}
+
+void* Heap::allocateLarge(std::lock_guard<StaticMutex>& lock, size_t alignment, size_t size)
+{
+ void* result = tryAllocateLarge(lock, alignment, size);
+ RELEASE_BASSERT(result);
+ return result;
+}
+
+bool Heap::isLarge(std::lock_guard<StaticMutex>&, void* object)
+{
+ return m_objectTypes.get(Object(object).chunk()) == ObjectType::Large;
+}
+
+size_t Heap::largeSize(std::lock_guard<StaticMutex>&, void* object)
+{
+ return m_largeAllocated.get(object);
+}
+
+void Heap::shrinkLarge(std::lock_guard<StaticMutex>&, const Range& object, size_t newSize)
+{
+ BASSERT(object.size() > newSize);
+
+ size_t size = m_largeAllocated.remove(object.begin());
+ LargeRange range = LargeRange(object, size);
+ splitAndAllocate(range, alignment, newSize);
+
+ scheduleScavenger(size);
+}
+
+void Heap::deallocateLarge(std::lock_guard<StaticMutex>&, void* object)
+{
+ size_t size = m_largeAllocated.remove(object);
+ m_largeFree.add(LargeRange(object, size, size));
+
+ scheduleScavenger(size);
+}
+
+} // namespace bmalloc
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Heap.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Heap.h
new file mode 100644
index 0000000000..bd4bb4463c
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Heap.h
@@ -0,0 +1,193 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef Heap_h
+#define Heap_h
+
+#include "AsyncTask.h"
+#include "BumpRange.h"
+#include "Environment.h"
+#include "LargeMap.h"
+#include "LineMetadata.h"
+#include "List.h"
+#include "Map.h"
+#include "Mutex.h"
+#include "Object.h"
+#include "SmallLine.h"
+#include "SmallPage.h"
+#include "VMHeap.h"
+#include "Vector.h"
+#include <array>
+#include <mutex>
+
+#if BOS(DARWIN)
+#include <dispatch/dispatch.h>
+#endif
+
+namespace bmalloc {
+
+class BeginTag;
+class BumpAllocator;
+class DebugHeap;
+class EndTag;
+
+class Heap {
+public:
+ Heap(std::lock_guard<StaticMutex>&);
+
+ DebugHeap* debugHeap() { return m_debugHeap; }
+
+ void allocateSmallBumpRanges(std::lock_guard<StaticMutex>&, size_t sizeClass, BumpAllocator&, BumpRangeCache&);
+ void derefSmallLine(std::lock_guard<StaticMutex>&, Object);
+
+ void* allocateLarge(std::lock_guard<StaticMutex>&, size_t alignment, size_t);
+ void* tryAllocateLarge(std::lock_guard<StaticMutex>&, size_t alignment, size_t);
+ void deallocateLarge(std::lock_guard<StaticMutex>&, void*);
+
+ bool isLarge(std::lock_guard<StaticMutex>&, void*);
+ size_t largeSize(std::lock_guard<StaticMutex>&, void*);
+ void shrinkLarge(std::lock_guard<StaticMutex>&, const Range&, size_t);
+
+ void scavenge(std::unique_lock<StaticMutex>&);
+
+ size_t memoryFootprint();
+ double percentAvailableMemoryInUse();
+ bool isUnderMemoryPressure();
+
+#if BOS(DARWIN)
+ void setScavengerThreadQOSClass(qos_class_t overrideClass) { m_requestedScavengerThreadQOSClass = overrideClass; }
+#endif
+
+private:
+ struct LargeObjectHash {
+ static unsigned hash(void* key)
+ {
+ return static_cast<unsigned>(
+ reinterpret_cast<uintptr_t>(key) / smallMax);
+ }
+ };
+
+ ~Heap() = delete;
+
+ void initializeLineMetadata();
+ void initializePageMetadata();
+
+ void allocateSmallBumpRangesByMetadata(std::lock_guard<StaticMutex>&,
+ size_t sizeClass, BumpAllocator&, BumpRangeCache&);
+ void allocateSmallBumpRangesByObject(std::lock_guard<StaticMutex>&,
+ size_t sizeClass, BumpAllocator&, BumpRangeCache&);
+
+ SmallPage* allocateSmallPage(std::lock_guard<StaticMutex>&, size_t sizeClass);
+
+ void deallocateSmallLine(std::lock_guard<StaticMutex>&, Object);
+
+ void mergeLarge(BeginTag*&, EndTag*&, Range&);
+ void mergeLargeLeft(EndTag*&, BeginTag*&, Range&, bool& inVMHeap);
+ void mergeLargeRight(EndTag*&, BeginTag*&, Range&, bool& inVMHeap);
+
+ LargeRange splitAndAllocate(LargeRange&, size_t alignment, size_t);
+
+ void scheduleScavenger(size_t);
+ void scheduleScavengerIfUnderMemoryPressure(size_t);
+
+ void concurrentScavenge();
+ void scavengeSmallPages(std::unique_lock<StaticMutex>&);
+ void scavengeLargeObjects(std::unique_lock<StaticMutex>&);
+
+#if BPLATFORM(IOS)
+ void updateMemoryInUseParameters();
+#endif
+
+ size_t m_vmPageSizePhysical;
+ Vector<LineMetadata> m_smallLineMetadata;
+ std::array<size_t, sizeClassCount> m_pageClasses;
+
+ std::array<List<SmallPage>, sizeClassCount> m_smallPagesWithFreeLines;
+ std::array<List<SmallPage>, pageClassCount> m_smallPages;
+
+ Map<void*, size_t, LargeObjectHash> m_largeAllocated;
+ LargeMap m_largeFree;
+
+ Map<Chunk*, ObjectType, ChunkHash> m_objectTypes;
+
+ size_t m_scavengerBytes { 0 };
+ bool m_isGrowing { false };
+
+ AsyncTask<Heap, decltype(&Heap::concurrentScavenge)> m_scavenger;
+
+ Environment m_environment;
+ DebugHeap* m_debugHeap;
+
+#if BPLATFORM(IOS)
+ size_t m_maxAvailableMemory;
+ size_t m_memoryFootprint;
+ double m_percentAvailableMemoryInUse;
+#endif
+
+ VMHeap m_vmHeap;
+
+#if BOS(DARWIN)
+ dispatch_source_t m_pressureHandlerDispatchSource;
+ qos_class_t m_requestedScavengerThreadQOSClass { QOS_CLASS_USER_INITIATED };
+#endif
+};
+
+inline void Heap::allocateSmallBumpRanges(
+ std::lock_guard<StaticMutex>& lock, size_t sizeClass,
+ BumpAllocator& allocator, BumpRangeCache& rangeCache)
+{
+ if (sizeClass < bmalloc::sizeClass(smallLineSize))
+ return allocateSmallBumpRangesByMetadata(lock, sizeClass, allocator, rangeCache);
+ return allocateSmallBumpRangesByObject(lock, sizeClass, allocator, rangeCache);
+}
+
+inline void Heap::derefSmallLine(std::lock_guard<StaticMutex>& lock, Object object)
+{
+ if (!object.line()->deref(lock))
+ return;
+ deallocateSmallLine(lock, object);
+}
+
+inline bool Heap::isUnderMemoryPressure()
+{
+#if BPLATFORM(IOS)
+ return percentAvailableMemoryInUse() > memoryPressureThreshold;
+#else
+ return false;
+#endif
+}
+
+#if BPLATFORM(IOS)
+inline size_t Heap::memoryFootprint()
+{
+ updateMemoryInUseParameters();
+
+ return m_memoryFootprint;
+}
+
+inline double Heap::percentAvailableMemoryInUse()
+{
+ updateMemoryInUseParameters();
+
+ return m_percentAvailableMemoryInUse;
+}
+#endif
+
+} // namespace bmalloc
+
+#endif // Heap_h
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Inline.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Inline.h
new file mode 100644
index 0000000000..a529313f4c
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/Inline.h
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef Inline_h
+#define Inline_h
+
+#define INLINE __attribute__((always_inline)) inline
+
+#define NO_INLINE __attribute__((noinline))
+
+#endif // Inline_h
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/LargeMap.cpp b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/LargeMap.cpp
new file mode 100644
index 0000000000..2b23e53bc8
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/LargeMap.cpp
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "LargeMap.h"
+#include <utility>
+
+namespace bmalloc {
+
+LargeRange LargeMap::remove(size_t alignment, size_t size)
+{
+ size_t alignmentMask = alignment - 1;
+
+ LargeRange* candidate = m_free.end();
+ for (LargeRange* it = m_free.begin(); it != m_free.end(); ++it) {
+ if (it->size() < size)
+ continue;
+
+ if (candidate != m_free.end() && candidate->begin() < it->begin())
+ continue;
+
+ if (test(it->begin(), alignmentMask)) {
+ char* aligned = roundUpToMultipleOf(alignment, it->begin());
+ if (aligned < it->begin()) // Check for overflow.
+ continue;
+
+ char* alignedEnd = aligned + size;
+ if (alignedEnd < aligned) // Check for overflow.
+ continue;
+
+ if (alignedEnd > it->end())
+ continue;
+ }
+
+ candidate = it;
+ }
+
+ if (candidate == m_free.end())
+ return LargeRange();
+
+ return m_free.pop(candidate);
+}
+
+void LargeMap::add(const LargeRange& range)
+{
+ LargeRange merged = range;
+
+ for (size_t i = 0; i < m_free.size(); ++i) {
+ if (!canMerge(merged, m_free[i]))
+ continue;
+
+ merged = merge(merged, m_free.pop(i--));
+ }
+
+ m_free.push(merged);
+}
+
+} // namespace bmalloc
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/LargeMap.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/LargeMap.h
new file mode 100644
index 0000000000..721ac3f449
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/LargeMap.h
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef LargeMap_h
+#define LargeMap_h
+
+#include "LargeRange.h"
+#include "Vector.h"
+#include <algorithm>
+
+namespace bmalloc {
+
+class LargeMap {
+public:
+ void add(const LargeRange&);
+ LargeRange remove(size_t alignment, size_t);
+ Vector<LargeRange>& ranges() { return m_free; }
+
+private:
+ Vector<LargeRange> m_free;
+};
+
+} // namespace bmalloc
+
+#endif // LargeMap_h
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/LargeRange.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/LargeRange.h
new file mode 100644
index 0000000000..d913030372
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/LargeRange.h
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef LargeRange_h
+#define LargeRange_h
+
+#include "BAssert.h"
+#include "Range.h"
+
+namespace bmalloc {
+
+class LargeRange : public Range {
+public:
+ LargeRange()
+ : Range()
+ , m_physicalSize(0)
+ {
+ }
+
+ LargeRange(const Range& other, size_t physicalSize)
+ : Range(other)
+ , m_physicalSize(physicalSize)
+ {
+ }
+
+ LargeRange(void* begin, size_t size, size_t physicalSize)
+ : Range(begin, size)
+ , m_physicalSize(physicalSize)
+ {
+ }
+
+ size_t physicalSize() const { return m_physicalSize; }
+ void setPhysicalSize(size_t physicalSize) { m_physicalSize = physicalSize; }
+
+ std::pair<LargeRange, LargeRange> split(size_t) const;
+
+ bool operator<(const void* other) const { return begin() < other; }
+ bool operator<(const LargeRange& other) const { return begin() < other.begin(); }
+
+private:
+ size_t m_physicalSize;
+};
+
+inline bool canMerge(const LargeRange& a, const LargeRange& b)
+{
+ if (a.end() == b.begin())
+ return true;
+
+ if (b.end() == a.begin())
+ return true;
+
+ return false;
+}
+
+inline LargeRange merge(const LargeRange& a, const LargeRange& b)
+{
+ const LargeRange& left = std::min(a, b);
+ if (left.size() == left.physicalSize()) {
+ return LargeRange(
+ left.begin(),
+ a.size() + b.size(),
+ a.physicalSize() + b.physicalSize());
+ }
+
+ return LargeRange(
+ left.begin(),
+ a.size() + b.size(),
+ left.physicalSize());
+}
+
+inline std::pair<LargeRange, LargeRange> LargeRange::split(size_t size) const
+{
+ BASSERT(size <= this->size());
+
+ if (size <= physicalSize()) {
+ LargeRange left(begin(), size, size);
+ LargeRange right(left.end(), this->size() - size, physicalSize() - size);
+ return std::make_pair(left, right);
+ }
+
+ LargeRange left(begin(), size, physicalSize());
+ LargeRange right(left.end(), this->size() - size, 0);
+ return std::make_pair(left, right);
+}
+
+} // namespace bmalloc
+
+#endif // LargeRange_h
diff --git a/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/LineMetadata.h b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/LineMetadata.h
new file mode 100644
index 0000000000..dba4e5a3c7
--- /dev/null
+++ b/weex_core/Source/android/jsengine/dependence/bmalloc/bmalloc/LineMetadata.h
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef LineMetadata_h
+#define LineMetadata_h
+
(This diff was longer than 20,000 lines, and has been truncated...)
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
With regards,
Apache Git Services