You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@weex.apache.org by GitBox <gi...@apache.org> on 2018/10/03 05:48:39 UTC

[GitHub] wqyfavor closed pull request #1605: [iOS] Add __enable_native_promise__ & __enable_native_timer__ to WXEn…

wqyfavor closed pull request #1605: [iOS] Add __enable_native_promise__ & __enable_native_timer__ to WXEn…
URL: https://github.com/apache/incubator-weex/pull/1605
 
 
   

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/android/sdk/libs/armeabi-v7a/libweexcore.so b/android/sdk/libs/armeabi-v7a/libweexcore.so
index dcd049243e..854d71feaf 100644
Binary files a/android/sdk/libs/armeabi-v7a/libweexcore.so and b/android/sdk/libs/armeabi-v7a/libweexcore.so differ
diff --git a/android/sdk/libs/armeabi-v7a/libweexjss.so b/android/sdk/libs/armeabi-v7a/libweexjss.so
index 0ea24f68a9..a5664ef28a 100755
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/libweexcore.so b/android/sdk/libs/armeabi/libweexcore.so
index 602f9b7483..9f540a72ef 100644
Binary files a/android/sdk/libs/armeabi/libweexcore.so and b/android/sdk/libs/armeabi/libweexcore.so differ
diff --git a/android/sdk/libs/armeabi/libweexjss.so b/android/sdk/libs/armeabi/libweexjss.so
index 0ea24f68a9..a5664ef28a 100755
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/libweexcore.so b/android/sdk/libs/x86/libweexcore.so
index 669a14ffa1..bee91b96e4 100644
Binary files a/android/sdk/libs/x86/libweexcore.so and b/android/sdk/libs/x86/libweexcore.so differ
diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
index 8189237211..5785fd3c0a 100644
--- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
+++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
@@ -1128,7 +1128,9 @@ public void fireEventOnNode(final String instanceId, final String ref,
       throw new WXRuntimeException(
               "fireEvent must be called by main thread");
     }
-    if (WXSDKManager.getInstance().getAllInstanceMap().get(instanceId)!=null && WXSDKManager.getInstance().getAllInstanceMap().get(instanceId).getRenderStrategy()== WXRenderStrategy.DATA_RENDER) {
+    WXSDKInstance instance = WXSDKManager.getInstance().getAllInstanceMap().get(instanceId);
+    if (instance != null && (instance.getRenderStrategy() == WXRenderStrategy.DATA_RENDER ||
+            instance.getRenderStrategy() == WXRenderStrategy.DATA_RENDER_BINARY)) {
       fireEventOnDataRenderNode(instanceId, ref, type, data);
     } else {
       if(callback == null) {
@@ -1470,7 +1472,14 @@ private void invokeCreateInstance(@NonNull WXSDKInstance instance, Script templa
         if (type == BundType.Vue || type == BundType.Rax
                 || instance.getRenderStrategy() == WXRenderStrategy.DATA_RENDER
                 || instance.getRenderStrategy() == WXRenderStrategy.DATA_RENDER_BINARY) {
-          invokeCreateInstanceContext(instance.getInstanceId(), null, "createInstanceContext", args, false);
+          int ret = invokeCreateInstanceContext(instance.getInstanceId(), null, "createInstanceContext", args, false);
+          if(ret == 0) {
+            String err = "[WXBridgeManager] invokeCreateInstance : " + instance.getTemplateInfo();
+
+            instance.onRenderError(
+                    WXErrorCode.WX_DEGRAD_ERR_INSTANCE_CREATE_FAILED.getErrorCode(),
+                    WXErrorCode.WX_DEGRAD_ERR_INSTANCE_CREATE_FAILED.getErrorMsg() + err);
+          }
           return;
         } else {
           invokeExecJS(instance.getInstanceId(), null, METHOD_CREATE_INSTANCE, args, false);
@@ -1693,7 +1702,7 @@ public void invokeExecJS(String instanceId, String namespace, String function,
     }
   }
 
-  public void invokeCreateInstanceContext(String instanceId, String namespace, String function,
+  public int invokeCreateInstanceContext(String instanceId, String namespace, String function,
                                           WXJSObject[] args, boolean logTaskDetail) {
     WXLogUtils.d("invokeCreateInstanceContext instanceId:" + instanceId + " function:"
             + function + " isJSFrameworkInit:%d" + isJSFrameworkInit());
@@ -1704,7 +1713,7 @@ public void invokeCreateInstanceContext(String instanceId, String namespace, Str
     WXLogUtils.d(mLodBuilder.substring(0));
     mLodBuilder.setLength(0);
     // }
-    mWXBridge.createInstanceContext(instanceId, namespace, function, args);
+    return mWXBridge.createInstanceContext(instanceId, namespace, function, args);
   }
 
   public void invokeDestoryInstance(String instanceId, String namespace, String function,
diff --git a/android/sdk/src/main/java/com/taobao/weex/common/IWXBridge.java b/android/sdk/src/main/java/com/taobao/weex/common/IWXBridge.java
index 20f53465ac..c998fe5da1 100644
--- a/android/sdk/src/main/java/com/taobao/weex/common/IWXBridge.java
+++ b/android/sdk/src/main/java/com/taobao/weex/common/IWXBridge.java
@@ -18,15 +18,11 @@
  */
 package com.taobao.weex.common;
 
-import com.taobao.weex.WXEnvironment;
-import com.taobao.weex.base.CalledByNative;
 import com.taobao.weex.bridge.ResultCallback;
-import com.taobao.weex.bridge.WXBridgeManager;
 import com.taobao.weex.bridge.WXJSObject;
 import com.taobao.weex.bridge.WXParams;
 import com.taobao.weex.dom.CSSShorthand;
 import com.taobao.weex.layout.ContentBoxMeasurement;
-
 import java.util.HashMap;
 import java.util.HashSet;
 
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.h b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.h
index b58d32731c..aa7e5a754f 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.h
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.h
@@ -116,6 +116,7 @@ namespace WeexCore
         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 {};
+        void OnReceivedResult(long callback_id, std::unique_ptr<WeexJSResult>& result) override {};
     };
     
     class WXCoreMeasureFunctionBridge : public MeasureFunctionAdapter
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
index 35402b112d..41c5d80286 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
@@ -205,8 +205,16 @@ static void MergeBorderWidthValues(NSMutableDictionary* dict,
     
     void IOSSide::ReportException(const char* pageId, const char *func, const char *exception_string)
     {
-        // should not enter this function
-        assert(false);
+        NSString* ns_instanceId = NSSTRING(pageId);
+
+        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
+        if (!manager.isValid) {
+            return;
+        }
+
+        int wxErrorCode = 9999;
+        NSError * error = [NSError errorWithDomain:WX_ERROR_DOMAIN code:wxErrorCode userInfo:@{@"message":[NSString stringWithUTF8String:exception_string]}];
+        [manager renderFailed:error];
     }
     
     int IOSSide::CallNative(const char* pageId, const char *task, const char *callback)
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.h b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.h
index 7791727874..94eb39973e 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.h
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.h
@@ -201,6 +201,11 @@ void WXPerformBlockSyncOnComponentThread(void (^block)(void));
  **/
 - (void)renderFinish;
 
+/**
+ * @abstract called when render failed
+ **/
+- (void)renderFailed:(NSError *)error;
+
 /**
  * @abstract unload
  **/
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm
index 8da19684ec..7ad5c45c6f 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm
@@ -864,6 +864,17 @@ - (void)renderFinish
     }];
 }
 
+- (void)renderFailed:(NSError *)error {
+    WXAssertComponentThread();
+
+    WXSDKInstance *instance  = self.weexInstance;
+    [self _addUITask:^{
+        if (instance.onFailed) {
+            instance.onFailed(error);
+        }
+    }];
+}
+
 - (void)unload
 {
     WXAssertComponentThread();
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
index 7927f00f9a..daf1fd6ad3 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
@@ -35,7 +35,7 @@
 #import <CommonCrypto/CommonCrypto.h>
 #import <CoreText/CoreText.h>
 #import "WXAppMonitorProtocol.h"
-
+#import "WXConfigCenterProtocol.h"
 #import "WXTextComponent.h"
 
 #define KEY_PASSWORD  @"com.taobao.Weex.123456"
@@ -45,6 +45,8 @@
 static BOOL unregisterFontWhenCollision = NO;
 static BOOL listSectionRowThreadSafe = YES;
 static BOOL useJSCApiForCreateInstance = YES;
+static BOOL jsfmEnableNativePromiseOnIOS11AndLater = YES; // 是否在高版本 iOS (11/12) 中使用原生 Promise
+static BOOL jsfmEnableNativeTimer = NO; // 是否使用原生 timer 接口
 
 void WXPerformBlockOnMainThread(void (^ _Nonnull block)(void))
 {
@@ -196,6 +198,16 @@ + (void)_performBlock:(void (^)(void))block
 
 + (NSDictionary *)getEnvironment
 {
+    id configCenter = [WXSDKEngine handlerForProtocol:@protocol(WXConfigCenterProtocol)];
+    if ([configCenter respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) {
+        // update
+        jsfmEnableNativePromiseOnIOS11AndLater = [[configCenter configForKey:@"iOS_weex_ext_config.jsfmEnableNativePromiseOnIOS11AndLater" defaultValue:@(YES) isDefault:NULL] boolValue];
+        jsfmEnableNativeTimer = [[configCenter configForKey:@"iOS_weex_ext_config.jsfmEnableNativeTimer" defaultValue:@(NO) isDefault:NULL] boolValue];
+    }
+    
+    BOOL jsfmEnableNativePromise = jsfmEnableNativePromiseOnIOS11AndLater &&
+        [[[UIDevice currentDevice] systemVersion] integerValue] >= 11;
+    
     NSString *platform = @"iOS";
     NSString *sysVersion = [[UIDevice currentDevice] systemVersion] ?: @"";
     NSString *weexVersion = WX_SDK_VERSION;
@@ -218,7 +230,9 @@ + (NSDictionary *)getEnvironment
                                     @"deviceWidth":@(deviceWidth * scale),
                                     @"deviceHeight":@(deviceHeight * scale),
                                     @"scale":@(scale),
-                                    @"logLevel":[WXLog logLevelString] ?: @"error"
+                                    @"logLevel":[WXLog logLevelString] ?: @"error",
+                                    @"__enable_native_promise__": @(jsfmEnableNativePromise),
+                                    @"__enable_native_timer__": @(jsfmEnableNativeTimer)
                                 }];
     if ([WXSDKEngine customEnvironment]) {
         [data addEntriesFromDictionary:[WXSDKEngine customEnvironment]];
diff --git a/runtime/shared/index.js b/runtime/shared/index.js
index 19ca3cd2a9..48b432a6fd 100644
--- a/runtime/shared/index.js
+++ b/runtime/shared/index.js
@@ -22,12 +22,15 @@ if (!process.env.SUPPORT_ES2015) {
   require('./polyfill/objectAssign')
   require('./polyfill/objectSetPrototypeOf')
 
-  // import promise hack and polyfills
-  require('./polyfill/promise')
-  require('core-js/modules/es6.object.to-string')
-  require('core-js/modules/es6.string.iterator')
-  require('core-js/modules/web.dom.iterable')
-  require('core-js/modules/es6.promise')
+  // eslint-disable-next-line
+  if (typeof WXEnvironment === 'undefined' || !WXEnvironment.__enable_native_promise__) {
+    // import promise hack and polyfill
+    require('./polyfill/promise')
+    require('core-js/modules/es6.object.to-string')
+    require('core-js/modules/es6.string.iterator')
+    require('core-js/modules/web.dom.iterable')
+    require('core-js/modules/es6.promise')
+  }
 }
 
 export * from './env/console'
diff --git a/runtime/shared/polyfill/promise.js b/runtime/shared/polyfill/promise.js
index 39fe8169b0..1bb0ee3654 100644
--- a/runtime/shared/polyfill/promise.js
+++ b/runtime/shared/polyfill/promise.js
@@ -23,6 +23,8 @@
 const { WXEnvironment } = global
 
 /* istanbul ignore next */
-if (WXEnvironment && WXEnvironment.platform === 'iOS') {
+if (typeof WXEnvironment !== 'undefined'
+  && WXEnvironment.platform === 'iOS'
+  && !WXEnvironment.__enable_native_promise__) {
   global.Promise = undefined
 }
diff --git a/weex_core/Source/android/base/jni/android_jni.cpp b/weex_core/Source/android/base/jni/android_jni.cpp
index 7385e7eb90..1402e96b9b 100644
--- a/weex_core/Source/android/base/jni/android_jni.cpp
+++ b/weex_core/Source/android/base/jni/android_jni.cpp
@@ -32,7 +32,13 @@ void InitVM(JavaVM *vm) {
 
 JNIEnv *AttachCurrentThread() {
   JNIEnv *env = nullptr;
-  jint ret = g_jvm->AttachCurrentThread(&env, nullptr);
+
+  JavaVMAttachArgs args;
+  args.version = JNI_VERSION_1_4;
+  args.name = "weex_sdk_runtime";
+  args.group = nullptr;
+
+  jint ret = g_jvm->AttachCurrentThread(&env, &args);
   return env;
 }
 
diff --git a/weex_core/Source/android/base/string/string_utils.h b/weex_core/Source/android/base/string/string_utils.h
index d09fd783af..6b42baec8e 100644
--- a/weex_core/Source/android/base/string/string_utils.h
+++ b/weex_core/Source/android/base/string/string_utils.h
@@ -64,8 +64,8 @@ static inline std::string jString2Str(JNIEnv *env, const jstring &jstr) {
 static inline std::string jString2StrFast(JNIEnv *env, const jstring &jstr){
   if (jstr == nullptr)
     return std::string("");
-  const char *nativeString = env->GetStringUTFChars(jstr, JNI_FALSE);
-  return std::string(nativeString);
+  auto nativeString = ScopedJStringUTF8(env, jstr);
+  return std::string(nativeString.getChars());
 }
 
 static std::string jByteArray2Str(JNIEnv *env, jbyteArray barr) {
diff --git a/weex_core/Source/android/wrap/wml_bridge.cpp b/weex_core/Source/android/wrap/wml_bridge.cpp
index 2113138d0f..c683c03dfe 100644
--- a/weex_core/Source/android/wrap/wml_bridge.cpp
+++ b/weex_core/Source/android/wrap/wml_bridge.cpp
@@ -188,22 +188,22 @@ const char kWMLBridgeClassPath[] = "com/taobao/windmill/bridge/WMLBridge";
 jclass g_WMLBridge_clazz = nullptr;
 
 static JNINativeMethod gWMMethods[] = {
-    {"initAppFramework",
+    {"nativeInitAppFramework",
      "(Ljava/lang/String;Ljava/lang/String;[Lcom/taobao/weex/bridge/"
      "WXJSObject;)I",
      (void*)InitAppFramework},
-    {"createAppContext",
+    {"nativeCreateAppContext",
      "(Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)I",
      (void*)CreateAppContext},
-    {"execJsOnApp",
+    {"nativeExecJsOnApp",
      "(Ljava/lang/String;Ljava/lang/String;"
      "[Lcom/taobao/weex/bridge/WXJSObject;)I",
      (void*)ExecJsOnApp},
-    {"execJsOnAppWithResult",
+    {"nativeExecJsOnAppWithResult",
      "(Ljava/lang/String;Ljava/lang/String;"
      "Ljava/util/Map;)[B",
      (void*)ExecJsOnAppWithResult},
-    {"destoryAppContext", "(Ljava/lang/String;)I", (void*)DestoryAppContext},
+    {"nativeDestoryAppContext", "(Ljava/lang/String;)I", (void*)DestoryAppContext},
 };
 
 static int registerWMLBridgeNativeMethods(JNIEnv* env, JNINativeMethod* methods,
diff --git a/weex_core/Source/android/wrap/wx_bridge.cpp b/weex_core/Source/android/wrap/wx_bridge.cpp
index a97d927388..e783eeeb13 100644
--- a/weex_core/Source/android/wrap/wx_bridge.cpp
+++ b/weex_core/Source/android/wrap/wx_bridge.cpp
@@ -170,10 +170,13 @@ static jlongArray GetRenderFinishTime(JNIEnv* env, jobject jcaller,
 
 // Notice that this method is invoked from main thread.
 static jboolean NotifyLayout(JNIEnv* env, jobject jcaller, jstring instanceId) {
-  return WeexCoreManager::Instance()
-      ->getPlatformBridge()
-      ->core_side()
-      ->NotifyLayout(jString2StrFast(env, instanceId));
+  if (WeexCoreManager::Instance()->getPlatformBridge()) {
+    return WeexCoreManager::Instance()
+        ->getPlatformBridge()
+        ->core_side()
+        ->NotifyLayout(jString2StrFast(env, instanceId));
+  }
+  return false;
 }
 
 // Notice that this method is invoked from JS thread.
diff --git a/weex_core/Source/core/data_render/binary_file.cc b/weex_core/Source/core/data_render/binary_file.cc
index 989e9aeea8..549a6698b7 100644
--- a/weex_core/Source/core/data_render/binary_file.cc
+++ b/weex_core/Source/core/data_render/binary_file.cc
@@ -18,13 +18,21 @@
  */
 
 #include "core/data_render/binary_file.h"
+#include "core/data_render/common_error.h"
 
 namespace weex {
 namespace core {
 namespace data_render {
     BinaryFile* BinaryFile::g_instance_ = nullptr;
 
-    BinaryFile::BinaryFile():fout_(nullptr), position_(0), length_(0){
+    BinaryFile::BinaryFile():fout_(nullptr), position_(0), length_(0) {
+        int32_t i=1;
+        char *b=(char *)&i;
+        if (*b == 1) {
+            little_endian_ = true;
+        } else {
+            little_endian_ = false;
+        }
     }
 
     BinaryFile* BinaryFile::instance() {
@@ -51,8 +59,17 @@ namespace data_render {
     }
 
     void BinaryFile::read(char *stream, unsigned count) {
-        for (int i=0; i<count; i++) {
-            stream[i] = input_[position_++];
+        if (position_ + count > length_) {
+            throw OpcodeDecodeError("Read data is error");
+        }
+        if (!little_endian_ && count > 1) {
+            for (int i=count-1; i>=0; i--) {
+                stream[i] = input_[position_++];
+            }
+        } else {
+            for (int i=0; i<count; i++) {
+                stream[i] = input_[position_++];
+            }
         }
     }
 
diff --git a/weex_core/Source/core/data_render/binary_file.h b/weex_core/Source/core/data_render/binary_file.h
index 9689932554..e8a31acb72 100644
--- a/weex_core/Source/core/data_render/binary_file.h
+++ b/weex_core/Source/core/data_render/binary_file.h
@@ -59,6 +59,7 @@ namespace data_render {
         const char* input_;
         unsigned long position_;
         unsigned long length_;
+        bool little_endian_;
     };
 }  // namespace data_render
 }  // namespace core
diff --git a/weex_core/Source/core/data_render/class_string.cc b/weex_core/Source/core/data_render/class_string.cc
index 2742d762cb..61a18aee46 100644
--- a/weex_core/Source/core/data_render/class_string.cc
+++ b/weex_core/Source/core/data_render/class_string.cc
@@ -182,7 +182,7 @@ char *url_encode(char *str) {
         if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
             *pbuf++ = *pstr;
         else if (*pstr == ' ')
-            *pbuf++ = '+';
+            *pbuf++ = '%', *pbuf++ = '2', *pbuf++ = '0';
         else
             *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
         pstr++;
@@ -230,6 +230,73 @@ Value encodeURIComponent(ExecState *exec_state) {
     }
     return exec_state->string_table()->StringFromUTF8(dst);
 }
+    
+std::string utf8chr(int cp)
+{
+    char c[5] = { 0x00,0x00,0x00,0x00,0x00 };
+    if (cp <= 0x7F) {
+        c[0] = cp;
+    }
+    else if (cp <= 0x7FF) {
+        c[0] = (cp >> 6) + 192;
+        c[1] = (cp & 63) + 128;
+    }
+    else if (0xd800 <= cp && cp <= 0xdfff) {
+        //invalid block of utf8
+    }
+    else if (cp <= 0xFFFF)
+    {
+        c[0] = (cp >> 12) + 224;
+        c[1]= ((cp >> 6) & 63) + 128;
+        c[2] = (cp & 63) + 128;
+    }
+    else if (cp <= 0x10FFFF) {
+        c[0] = (cp >> 18) + 240;
+        c[1] = ((cp >> 12) & 63) + 128;
+        c[2] = ((cp >> 6) & 63) + 128;
+        c[3] = (cp & 63) + 128;
+    }
+    return std::string(c);
+}
+    
+std::string utf8_decode(std::string &input) {
+    do {
+        size_t length = input.length();
+        if (!length) {
+            break;
+        }
+        const char *chars = input.c_str();
+        std::string utf8str = "";
+        for (int i = 0; i < length; i++) {
+            char c = chars[i];
+            if (c == '\\' && chars[i + 1] == 'u') {
+                int cc = 0;
+                for (int j = 0; j < 4; j++)
+                {
+                    char ch = tolower(chars[i + 2 + j]);
+                    if (('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f')) {
+                        cc|= (from_hex(ch) << (3 - j) * 4);
+                    }
+                    else
+                    {
+                        cc = 0;
+                        break;
+                    }
+                }
+                if (cc) {
+                    i += 5;
+                    utf8str += utf8chr(cc);
+                    continue;
+                }
+            }
+            utf8str.push_back(c);
+        }
+        return utf8str;
+        
+    } while (0);
+    
+    return input;
+}
 
 Value indexOf(ExecState* exec_state) {
     size_t length = exec_state->GetArgumentCount();
diff --git a/weex_core/Source/core/data_render/class_string.h b/weex_core/Source/core/data_render/class_string.h
index 89072355d1..9aa32751f6 100644
--- a/weex_core/Source/core/data_render/class_string.h
+++ b/weex_core/Source/core/data_render/class_string.h
@@ -32,6 +32,7 @@ namespace data_render {
         
 ClassDescriptor *NewClassString();
 Value encodeURIComponent(ExecState *exec_state);
+std::string utf8_decode(std::string &input);
     
 }  // namespace data_render
 }  // namespace core
diff --git a/weex_core/Source/core/data_render/code_generator.cc b/weex_core/Source/core/data_render/code_generator.cc
index fab8367310..bb1816b74b 100644
--- a/weex_core/Source/core/data_render/code_generator.cc
+++ b/weex_core/Source/core/data_render/code_generator.cc
@@ -431,10 +431,12 @@ void CodeGenerator::Visit(FunctionStatement *node, void *data) {
         // make arguments var in thie front of stack;
         if (is_class_func) {
             block_->AddVariable("this", block_->NextRegisterId());
+            func_->func_state()->argc()++;
         }
         for (int i = 0; i < proto->GetArgs().size(); i++) {
             std::string arg = proto->GetArgs().at(i);
             block_->AddVariable(arg, block_->NextRegisterId());
+            func_->func_state()->argc()++;
         }
         node->body()->Accept(this, nullptr);
     }
@@ -505,18 +507,21 @@ void CodeGenerator::Visit(ArrowFunctionStatement *node, void *data) {
         // make arguments var in thie front of stack;
         if (is_class_func) {
             block_->AddVariable("this", block_->NextRegisterId());
+            func_->func_state()->argc()++;
         }
         // make arguments var in thie front of stack;
         for (int i = 0; i < node->args().size(); i++) {
             if (node->args()[i]->IsIdentifier()) {
                 std::string arg = node->args()[i]->AsIdentifier()->GetName();
                 block_->AddVariable(arg, block_->NextRegisterId());
+                func_->func_state()->argc()++;
             }
             else if (node->args()[i]->IsCommaExpression()) {
                 Handle<ExpressionList> arg_list = node->args()[i]->AsCommaExpression()->exprs();
                 for (int j = 0; j < arg_list->Size(); j++) {
                     std::string arg = arg_list->raw_list()[j]->AsIdentifier()->GetName();
                     block_->AddVariable(arg, block_->NextRegisterId());
+                    func_->func_state()->argc()++;
                 }
             }
             else {
diff --git a/weex_core/Source/core/data_render/common_error.h b/weex_core/Source/core/data_render/common_error.h
index 2a552d345a..93b4e55be4 100644
--- a/weex_core/Source/core/data_render/common_error.h
+++ b/weex_core/Source/core/data_render/common_error.h
@@ -63,6 +63,12 @@ class VMExecError : public Error {
     VMExecError(std::string str)
     : Error("[VMExecError]", std::move(str)) { }
 };
+
+class OpcodeDecodeError : public Error {
+public:
+    OpcodeDecodeError(std::string str)
+    : Error("[OpcodeDecodeError]", std::move(str)) { }
+};
     
 class SyntaxError : public JSError {
 public:
diff --git a/weex_core/Source/core/data_render/exec_state.cc b/weex_core/Source/core/data_render/exec_state.cc
index ae567ca65c..587078fb09 100644
--- a/weex_core/Source/core/data_render/exec_state.cc
+++ b/weex_core/Source/core/data_render/exec_state.cc
@@ -128,8 +128,8 @@ void ExecState::startEncode() {
 
     int magic_number = 0x6d736100;
     unsigned version = 1;
-    file->write((char*)&magic_number, sizeof(int));
-    file->write((char*)&version, sizeof(unsigned));
+    file->write((char*)&magic_number, sizeof(int32_t));
+    file->write((char*)&version, sizeof(u_int32_t));
 
     encodeStringSection();
     encodeTableSection();
@@ -150,8 +150,8 @@ void ExecState::encodeStringSection() {
     unsigned size = static_cast<unsigned>(store.size());
     BinaryFile* file = BinaryFile::instance();
 
-    file->write((char*)&id, sizeof(unsigned));
-    file->write((char*)&size, sizeof(unsigned));
+    file->write((char*)&id, sizeof(u_int32_t));
+    file->write((char*)&size, sizeof(u_int32_t));
     for (auto &mapString : store) {
         unsigned length = static_cast<unsigned int>(mapString.first.length()) + 1;
         file->write(mapString.first.c_str(), static_cast<unsigned int>(sizeof(char) * length));
@@ -164,11 +164,11 @@ void ExecState::encodeArraySection() {
     unsigned size = static_cast<unsigned>(arrays.size());
     BinaryFile* file = BinaryFile::instance();
 
-    file->write((char*)&id, sizeof(unsigned));
-    file->write((char*)&size, sizeof(unsigned));
+    file->write((char*)&id, sizeof(u_int32_t));
+    file->write((char*)&size, sizeof(u_int32_t));
     for (auto array : arrays) {
         unsigned itemSize = static_cast<unsigned>(array->items.size());
-        file->write((char*)&itemSize, sizeof(unsigned));
+        file->write((char*)&itemSize, sizeof(u_int32_t));
         for (auto &value : array->items) {
             encodeValue(value);
         }
@@ -182,12 +182,12 @@ void ExecState::encodeTableSection() {
     unsigned size = static_cast<unsigned>(tables.size());
     BinaryFile* file = BinaryFile::instance();
 
-    file->write((char*)&id, sizeof(unsigned));
-    file->write((char*)&size, sizeof(unsigned));
+    file->write((char*)&id, sizeof(u_int32_t));
+    file->write((char*)&size, sizeof(u_int32_t));
 
     for (auto table : tables) {
         unsigned mapSize = static_cast<unsigned>(table->map.size());
-        file->write((char*)&mapSize, sizeof(unsigned));
+        file->write((char*)&mapSize, sizeof(u_int32_t));
         for (auto &map : table->map) {
             std::string name = map.first;
             Value value = map.second;
@@ -211,8 +211,8 @@ void ExecState::encodeFunctionSection() {
         func_states.push_back(func);
     }
     unsigned size = static_cast<unsigned>(func_states.size());
-    file->write((char*)&id, sizeof(unsigned));
-    file->write((char*)&size, sizeof(unsigned));
+    file->write((char*)&id, sizeof(u_int32_t));
+    file->write((char*)&size, sizeof(u_int32_t));
 
     for (auto &func_state : func_states) {
         auto it = std::find(func_states.begin(), func_states.end(), func_state->super_func());
@@ -220,20 +220,23 @@ void ExecState::encodeFunctionSection() {
         if (it != func_states.end()) {
             super_index = static_cast<int>(it - func_states.begin());
         }
-        file->write((char*)&super_index, sizeof(int));
+        file->write((char*)&super_index, sizeof(int32_t));
 
         bool is_class_func = func_state->is_class_func();
-        file->write((char*)&is_class_func, sizeof(int));
+        file->write((char*)&is_class_func, sizeof(int8_t));
+
+        int argc = func_state->argc();
+        file->write((char*)&argc, sizeof(int32_t));
 
         unsigned opcodeSize = static_cast<unsigned>(func_state->instructions().size());
-        file->write((char*)&opcodeSize, sizeof(unsigned));
+        file->write((char*)&opcodeSize, sizeof(u_int32_t));
         for (int i=0; i<opcodeSize; i++) {
             unsigned opcode = static_cast<unsigned>(func_state->instructions()[i]);
-            file->write((char*)&opcode, sizeof(unsigned));
+            file->write((char*)&opcode, sizeof(u_int32_t));
         }
 
         unsigned constantSize = static_cast<unsigned>(func_state->GetConstantSize());
-        file->write((char*)&constantSize, sizeof(unsigned));
+        file->write((char*)&constantSize, sizeof(u_int32_t));
         for (int i=0; i<constantSize; i++) {
             encodeValue(*(func_state->GetConstant(i)));
         }
@@ -244,8 +247,8 @@ void ExecState::encodeStartSection() {
     BinaryFile* file = BinaryFile::instance();
     unsigned id = Section::START_SECTION;
     unsigned index = 0;
-    file->write((char*)&id, sizeof(unsigned));
-    file->write((char*)&index, sizeof(unsigned));
+    file->write((char*)&id, sizeof(u_int32_t));
+    file->write((char*)&index, sizeof(u_int32_t));
 }
 
 void ExecState::encodeGlobalSection() {
@@ -253,12 +256,12 @@ void ExecState::encodeGlobalSection() {
     unsigned id = Section::GLOBAL_SECTION;
     unsigned size = static_cast<unsigned>(global_->size()) - global_->register_size();
 
-    file->write((char*)&id, sizeof(unsigned));
-    file->write((char*)&size, sizeof(unsigned));
+    file->write((char*)&id, sizeof(u_int32_t));
+    file->write((char*)&size, sizeof(u_int32_t));
     int init_data_index = global_->IndexOf("_init_data");
     int weex_data_index = global_->IndexOf("__weex_data__");
-    file->write((char*)&init_data_index, sizeof(int));
-    file->write((char*)&weex_data_index, sizeof(int));
+    file->write((char*)&init_data_index, sizeof(int32_t));
+    file->write((char*)&weex_data_index, sizeof(int32_t));
 
     for (int i=global_->register_size(); i<global_->size(); i++) {
         Value* value = global_->Find(i);
@@ -271,12 +274,12 @@ void ExecState::encodeGlobalVariableSection() {
     unsigned id = Section::GLOBAL_VARIABLE_SECTION;
     unsigned size = static_cast<unsigned>(global_variables_.size());
 
-    file->write((char*)&id, sizeof(unsigned));
-    file->write((char*)&size, sizeof(unsigned));
+    file->write((char*)&id, sizeof(u_int32_t));
+    file->write((char*)&size, sizeof(u_int32_t));
     for (auto variable : global_variables_) {
         unsigned length = static_cast<unsigned>(variable.first.length()) + 1;
         file->write(variable.first.c_str(), static_cast<unsigned int>(sizeof(char) * length));
-        file->write((char*)&variable.second, sizeof(long));
+        file->write((char*)&variable.second, sizeof(int64_t));
     }
 }
 
@@ -287,15 +290,15 @@ void ExecState::encodeStyleSection() {
     unsigned size = static_cast<unsigned>(styles.size());
     BinaryFile* file = BinaryFile::instance();
 
-    file->write((char*)&id, sizeof(unsigned));
-    file->write((char*)&size, sizeof(unsigned));
+    file->write((char*)&id, sizeof(u_int32_t));
+    file->write((char*)&size, sizeof(u_int32_t));
 
     for (auto style : styles) {
         Value value(string_table()->StringFromUTF8(style.first));
         encodeValue(value);
         const json11::Json::object& items = style.second.object_items();
         unsigned itemsSize = static_cast<unsigned>(items.size());
-        file->write((char*)&itemsSize, sizeof(unsigned));
+        file->write((char*)&itemsSize, sizeof(u_int32_t));
         for (auto it = items.begin(); it != items.end(); it++) {
             unsigned length = static_cast<unsigned>(it->first.length()) + 1;
             file->write(it->first.c_str(), static_cast<unsigned int>(sizeof(char) * length));
@@ -311,15 +314,15 @@ void ExecState::encodeRefSection() {
     unsigned size = static_cast<unsigned>(refs_.size());
     BinaryFile* file = BinaryFile::instance();
 
-    file->write((char*)&id, sizeof(unsigned));
-    file->write((char*)&size, sizeof(unsigned));
+    file->write((char*)&id, sizeof(u_int32_t));
+    file->write((char*)&size, sizeof(u_int32_t));
     for (auto ref : refs_) {
         Value value;
         value.type = Value::Type::FUNC;
         value.f = ref->func_state_;
         encodeValue(value);
         long register_id = ref->register_id();
-        file->write((char*)&register_id, sizeof(long));
+        file->write((char*)&register_id, sizeof(int64_t));
         encodeValue(ref->value_);
     }
 }
@@ -331,8 +334,8 @@ void ExecState::encodeClassSection() {
     unsigned size = static_cast<unsigned>(descs.size());
     BinaryFile* file = BinaryFile::instance();
 
-    file->write((char*)&id, sizeof(unsigned));
-    file->write((char*)&size, sizeof(unsigned));
+    file->write((char*)&id, sizeof(u_int32_t));
+    file->write((char*)&size, sizeof(u_int32_t));
 
     int count = 0;
     for (auto desc : descs) {
@@ -342,9 +345,9 @@ void ExecState::encodeClassSection() {
         }
 
         int superIndex = class_factory_->findDesc(desc->p_super_);
-        file->write((char*)&superIndex, sizeof(int));
+        file->write((char*)&superIndex, sizeof(int32_t));
         unsigned static_func_size = static_cast<unsigned>(desc->static_funcs_->size());
-        file->write((char*)&static_func_size, sizeof(unsigned));
+        file->write((char*)&static_func_size, sizeof(u_int32_t));
         for (int i=0; i<static_func_size; i++) {
             Value* value = desc->static_funcs_->Find(i);
             encodeValue(*value);
@@ -353,18 +356,18 @@ void ExecState::encodeClassSection() {
             for (auto &item : desc->static_funcs_->map()) {
                 if (item.second == i) {
                     length = static_cast<unsigned>(item.first.length()) + 1;
-                    file->write((char*)&length, sizeof(unsigned));
+                    file->write((char*)&length, sizeof(u_int32_t));
                     file->write(item.first.c_str(), static_cast<unsigned int>(sizeof(char) * length));
                     break;
                 }
             }
             if (length == 0) {
-                file->write((char*)&length, sizeof(unsigned));
+                file->write((char*)&length, sizeof(u_int32_t));
             }
         }
 
         unsigned class_func_size = static_cast<unsigned>(desc->funcs_->size());
-        file->write((char*)&class_func_size, sizeof(unsigned));
+        file->write((char*)&class_func_size, sizeof(u_int32_t));
         for (int i=0; i<class_func_size; i++) {
             Value* value = desc->funcs_->Find(i);
             encodeValue(*value);
@@ -373,13 +376,13 @@ void ExecState::encodeClassSection() {
             for (auto &item : desc->funcs_->map()) {
                 if (item.second == i) {
                     length = static_cast<unsigned>(item.first.length()) + 1;
-                    file->write((char*)&length, sizeof(unsigned));
+                    file->write((char*)&length, sizeof(u_int32_t));
                     file->write(item.first.c_str(), static_cast<unsigned int>(sizeof(char) * length));
                     break;
                 }
             }
             if (length == 0) {
-                file->write((char*)&length, sizeof(unsigned));
+                file->write((char*)&length, sizeof(u_int32_t));
             }
         }
     }
@@ -387,7 +390,7 @@ void ExecState::encodeClassSection() {
 
 void ExecState::encodeValue(const Value &value) {
     BinaryFile* file = BinaryFile::instance();
-    file->write((char*)&value.type, sizeof(unsigned));
+    file->write((char*)&value.type, sizeof(u_int32_t));
 
     if (value.type == Value::Type::TABLE) {
         std::vector<Table *> tables = class_factory_->tables();
@@ -398,7 +401,7 @@ void ExecState::encodeValue(const Value &value) {
             }
             payload++;
         }
-        file->write((char*)&payload, sizeof(int));
+        file->write((char*)&payload, sizeof(int32_t));
     }
 
     if (value.type == Value::Type::STRING) {
@@ -411,7 +414,7 @@ void ExecState::encodeValue(const Value &value) {
             }
             payload++;
         }
-        file->write((char*)&payload, sizeof(int));
+        file->write((char*)&payload, sizeof(int32_t));
     }
 
     if (value.type == Value::Type::INT) {
@@ -442,7 +445,7 @@ void ExecState::encodeValue(const Value &value) {
             }
             payload++;
         }
-        file->write((char*)&payload, sizeof(int));
+        file->write((char*)&payload, sizeof(int32_t));
     }
 
     if (value.type == Value::Type::ARRAY) {
@@ -454,7 +457,7 @@ void ExecState::encodeValue(const Value &value) {
             }
             payload++;
         }
-        file->write((char*)&payload, sizeof(int));
+        file->write((char*)&payload, sizeof(int32_t));
     }
 
     if (value.type == Value::Type::CLASS_DESC) {
@@ -466,7 +469,7 @@ void ExecState::encodeValue(const Value &value) {
             }
             payload++;
         }
-        file->write((char*)&payload, sizeof(int));
+        file->write((char*)&payload, sizeof(int32_t));
     }
 }
 
@@ -480,19 +483,19 @@ bool ExecState::startDecode() {
 
     BinaryFile* file = BinaryFile::instance();
     int magic_number;
-    file->read((char*)&magic_number, sizeof(int));
+    file->read((char*)&magic_number, sizeof(int32_t));
     if (magic_number != 0x6d736100) {
-        return false;
+        throw OpcodeDecodeError("The format of file is not wasm");
     }
     unsigned version;
-    file->read((char*)&version, sizeof(unsigned));
-    if (version != 1) {
-        return false;
+    file->read((char*)&version, sizeof(u_int32_t));
+    if (version > 1) {
+        throw OpcodeDecodeError("The version of file can not support");
     }
 
     while (!file->eof()) {
         Section section_id = NULL_SECTION;
-        file->read((char*)&section_id, sizeof(unsigned));
+        file->read((char*)&section_id, sizeof(u_int32_t));
         switch (section_id) {
             case STRING_SECTION:
                 decodeStringSection();
@@ -536,7 +539,7 @@ void ExecState::decodeStringSection()
     BinaryFile* file = BinaryFile::instance();
 
     unsigned count = 0;
-    file->read((char*)&count, sizeof(unsigned));
+    file->read((char*)&count, sizeof(u_int32_t));
     if (count == 0) {
         return;
     }
@@ -559,7 +562,7 @@ void ExecState::decodeTableSection() {
     BinaryFile* file = BinaryFile::instance();
 
     unsigned count = 0;
-    file->read((char*)&count, sizeof(unsigned));
+    file->read((char*)&count, sizeof(u_int32_t));
     if (count == 0) {
         return;
     }
@@ -568,7 +571,7 @@ void ExecState::decodeTableSection() {
         Value tableValue = class_factory_->CreateTable();
         Table* table = reinterpret_cast<Table *>(tableValue.gc);
         unsigned mapSize=0;
-        file->read((char*)&mapSize, sizeof(unsigned));
+        file->read((char*)&mapSize, sizeof(u_int32_t));
         for (int j=0; j<mapSize; j++) {
             std::string str;
             char c;
@@ -590,7 +593,7 @@ void ExecState::decodeFunctionSection() {
     BinaryFile* file = BinaryFile::instance();
 
     unsigned count = 0;
-    file->read((char*)&count, sizeof(unsigned));
+    file->read((char*)&count, sizeof(u_int32_t));
     if (count == 0) {
         return;
     }
@@ -599,22 +602,26 @@ void ExecState::decodeFunctionSection() {
     for (int i=0; i<count; i++) {
         FuncState* func_state = new FuncState;
         int super_index = -1;
-        file->read((char*)&super_index, sizeof(int));
+        file->read((char*)&super_index, sizeof(int32_t));
         func_state->set_super_index(super_index);
 
         bool is_class_func = false;
-        file->read((char*)&is_class_func, sizeof(bool));
+        file->read((char*)&is_class_func, sizeof(int8_t));
         func_state->set_is_class_func(is_class_func);
 
+        int argc = 0;
+        file->read((char*)&argc, sizeof(int32_t));
+        func_state->argc() = argc;
+
         unsigned op_code_count = 0;
-        file->read((char*)&op_code_count, sizeof(unsigned));
+        file->read((char*)&op_code_count, sizeof(u_int32_t));
         for (int j=0; j<op_code_count; j++) {
             unsigned opcode;
-            file->read((char*)&opcode, sizeof(unsigned));
+            file->read((char*)&opcode, sizeof(u_int32_t));
             func_state->AddInstruction(opcode);
         }
         unsigned local_count = 0;
-        file->read((char*)&local_count, sizeof(unsigned));
+        file->read((char*)&local_count, sizeof(u_int32_t));
         for (int j=0; j<local_count; j++) {
             Value value;
             decodeValue(value);
@@ -635,19 +642,19 @@ void ExecState::decodeFunctionSection() {
 void ExecState::decodeStartSection() {
     BinaryFile* file = BinaryFile::instance();
     unsigned start_index;
-    file->read((char*)&start_index, sizeof(unsigned));
+    file->read((char*)&start_index, sizeof(u_int32_t));
 }
 
 void ExecState::decodeGlobalSection() {
     BinaryFile* file = BinaryFile::instance();
 
     unsigned count = 0;
-    file->read((char*)&count, sizeof(unsigned));
+    file->read((char*)&count, sizeof(u_int32_t));
 
     int init_data_index = -1;
     int weex_data_index = -1;
-    file->read((char*)&init_data_index, sizeof(int));
-    file->read((char*)&weex_data_index, sizeof(int));
+    file->read((char*)&init_data_index, sizeof(int32_t));
+    file->read((char*)&weex_data_index, sizeof(int32_t));
 
     unsigned register_size = global_->register_size();
     for (int i=0; i<count; i++) {
@@ -669,7 +676,7 @@ void ExecState::decodeGlobalVariableSection() {
     BinaryFile* file = BinaryFile::instance();
 
     unsigned count = 0;
-    file->read((char*)&count, sizeof(unsigned));
+    file->read((char*)&count, sizeof(u_int32_t));
     if (count == 0) {
         return;
     }
@@ -695,7 +702,7 @@ void ExecState::decodeStyleSection() {
     BinaryFile* file = BinaryFile::instance();
 
     unsigned count = 0;
-    file->read((char*)&count, sizeof(unsigned));
+    file->read((char*)&count, sizeof(u_int32_t));
     if (count == 0) {
         return;
     }
@@ -705,7 +712,7 @@ void ExecState::decodeStyleSection() {
         decodeValue(value);
 
         unsigned itemsSize = 0;
-        file->read((char*)&itemsSize, sizeof(unsigned));
+        file->read((char*)&itemsSize, sizeof(u_int32_t));
         //json11::Json::object items;
         std::unordered_map<std::string, json11::Json> items;
         for (int j=0; j<itemsSize; j++) {
@@ -739,12 +746,12 @@ void ExecState::decodeStyleSection() {
 void ExecState::decodeArraySection() {
     BinaryFile* file = BinaryFile::instance();
     unsigned count = 0;
-    file->read((char*)&count, sizeof(unsigned));
+    file->read((char*)&count, sizeof(u_int32_t));
     for (int i=0; i<count; i++) {
         Value value = class_factory_->CreateArray();
         Array* array = reinterpret_cast<Array *>(value.gc);
         unsigned itemSize = 0;
-        file->read((char*)&itemSize, sizeof(unsigned));
+        file->read((char*)&itemSize, sizeof(u_int32_t));
         for (int j=0; j<itemSize; j++) {
             Value itemValue;
             decodeValue(itemValue);
@@ -756,7 +763,7 @@ void ExecState::decodeArraySection() {
 void ExecState::decodeRefSection() {
     BinaryFile* file = BinaryFile::instance();
     unsigned count = 0;
-    file->read((char*)&count, sizeof(unsigned));
+    file->read((char*)&count, sizeof(u_int32_t));
     for (int i=0; i<count; i++) {
         Value value;
         decodeValue(value);
@@ -772,23 +779,23 @@ void ExecState::decodeRefSection() {
 void ExecState::decodeClassSection() {
     BinaryFile* file = BinaryFile::instance();
     unsigned count = 0;
-    file->read((char*)&count, sizeof(unsigned));
+    file->read((char*)&count, sizeof(u_int32_t));
 
     size_t size = class_factory_->descs().size();
     for (int i=0; i<count - size; i++) {
         Value value = class_factory_->CreateClassDescriptor(nullptr);
         ClassDescriptor* desc = reinterpret_cast<ClassDescriptor *>(value.gc);
         int super_index = -1;
-        file->read((char*)&super_index, sizeof(int));
+        file->read((char*)&super_index, sizeof(int32_t));
         desc->super_index_ = super_index;
 
         unsigned static_func_size = 0;
-        file->read((char*)&static_func_size, sizeof(unsigned));
+        file->read((char*)&static_func_size, sizeof(u_int32_t));
         for (int j=0; j<static_func_size; j++) {
             Value static_value;
             decodeValue(static_value);
             unsigned length = 0;
-            file->read((char*)&length, sizeof(unsigned));
+            file->read((char*)&length, sizeof(u_int32_t));
             if (length > 0) {
                 std::unique_ptr<char[]> str(new char[length]);
                 file->read(str.get(), sizeof(char)*length);
@@ -799,13 +806,13 @@ void ExecState::decodeClassSection() {
         }
 
         unsigned class_func_size = 0;
-        file->read((char*)&class_func_size, sizeof(unsigned));
+        file->read((char*)&class_func_size, sizeof(u_int32_t));
         for (int j=0; j<class_func_size; j++) {
             Value class_value;
             decodeValue(class_value);
 
             unsigned length = 0;
-            file->read((char*)&length, sizeof(unsigned));
+            file->read((char*)&length, sizeof(u_int32_t));
             if (length > 0) {
                 std::unique_ptr<char[]> str(new char[length]);
                 file->read(str.get(), sizeof(char)*length);
@@ -820,7 +827,7 @@ void ExecState::decodeClassSection() {
 void ExecState::decodeValue(Value &value) {
     BinaryFile* file = BinaryFile::instance();
     unsigned valueType;
-    file->read((char*)&valueType, sizeof(int));
+    file->read((char*)&valueType, sizeof(u_int32_t));
     value.type = Value::Type(valueType);
 
     switch (valueType) {
@@ -830,7 +837,7 @@ void ExecState::decodeValue(Value &value) {
         case Value::Type::ARRAY:
         case Value::Type::CLASS_DESC: {
             value.gc = nullptr;
-            file->read((char*)&(value.index), sizeof(int));
+            file->read((char*)&(value.index), sizeof(int32_t));
         }
             break;
         case Value::Type::INT: {
@@ -1062,9 +1069,8 @@ void ExecState::Register(const std::string& name, Value value) {
 }
 
 void ExecState::CallFunction(Value *func, size_t argc, Value *ret) {
-    *stack_->top() = func + argc;
-    //LOGD("ExecStack::CallFunction:%i\n", (int)(func - stack_->base()));
     if (func->type == Value::Type::CFUNC) {
+        *stack_->top() = func + argc;
         Frame frame;
         frame.reg = func;
         frames_.push_back(frame);
@@ -1076,6 +1082,11 @@ void ExecState::CallFunction(Value *func, size_t argc, Value *ret) {
         frames_.pop_back();
     }
     else {
+        if (argc < func->f->argc()) {
+            size_t size = (func->f->argc() - argc) * sizeof(Value);
+            memset(func + argc + 1, 0, size);
+        }
+        *stack_->top() = func + argc;
         Frame frame;
         frame.func = func;
         frame.reg = func;
diff --git a/weex_core/Source/core/data_render/exec_state.h b/weex_core/Source/core/data_render/exec_state.h
index a256572ac9..c189bbd853 100644
--- a/weex_core/Source/core/data_render/exec_state.h
+++ b/weex_core/Source/core/data_render/exec_state.h
@@ -73,7 +73,7 @@ class FuncState {
     return (int)constants_.size() - 1;
   }
 
-  inline Value* GetConstant(int index) { return &constants_[index]; }
+  inline Value *GetConstant(int index) { return &constants_[index]; }
   inline size_t GetConstantSize() { return constants_.size();}
   inline size_t AddInstruction(Instruction i) {
     instructions_.push_back(i);
@@ -98,6 +98,7 @@ class FuncState {
   inline void set_is_class_func(bool is_class_func) { is_class_func_ = is_class_func; }
   inline bool is_class_func() { return is_class_func_; }
   inline ClassInstance * &class_inst() { return class_inst_; }
+  inline int &argc() { return argc_; }
   std::vector<FuncState *> getAllChildren() {
       std::vector<FuncState*> all_children;
       for (auto &child : children_) {
@@ -119,6 +120,7 @@ class FuncState {
   int super_index_;
   bool is_class_func_{false};
   ClassInstance *class_inst_{nullptr};
+  int argc_{0};
 };
     
 // TODO Each Func should contain a stack whose size is 256
diff --git a/weex_core/Source/core/data_render/tokenizer.cc b/weex_core/Source/core/data_render/tokenizer.cc
index ff88232a10..a229196032 100644
--- a/weex_core/Source/core/data_render/tokenizer.cc
+++ b/weex_core/Source/core/data_render/tokenizer.cc
@@ -1,6 +1,7 @@
 #include "core/data_render/tokenizer.h"
 #include "core/data_render/token.h"
 #include "core/data_render/scanner.h"
+#include "core/data_render/class_string.h"
 
 #include <cstring>
 #include <cassert>
@@ -556,11 +557,15 @@ Token Tokenizer::ParseString(char delim) {
   auto seek = _ seek();
   auto position = _ position();
   char ch = _ ReadChar();
+  bool utf8 = false;
   while (ch != EOF && ch != delim) {
     // escape characters
     if (ch == '\\') {
       buffer.push_back(ch);
       ch = _ ReadChar();
+      if (tolower(ch) == 'u') {
+          utf8 = true;
+      }
       if (ch == EOF) {
         break;
       }
@@ -568,13 +573,15 @@ Token Tokenizer::ParseString(char delim) {
     buffer.push_back(ch);
     ch = _ ReadChar();
   }
-
   if (ch == EOF) {
     return Token(std::string("EOF"), Token::ERROR, position, seek);
   }
 
   Token::Type type = delim == '`' ? Token::TEMPLATE : Token::STRING;
-
+  
+  if (utf8) {
+      buffer = utf8_decode(buffer);
+  }
   return Token(buffer, type, position, seek);
 }
 
diff --git a/weex_core/Source/core/data_render/vnode/vnode_exec_env.cc b/weex_core/Source/core/data_render/vnode/vnode_exec_env.cc
index 8623ace2a2..6dab8b0e1a 100644
--- a/weex_core/Source/core/data_render/vnode/vnode_exec_env.cc
+++ b/weex_core/Source/core/data_render/vnode/vnode_exec_env.cc
@@ -407,12 +407,7 @@ static Value AppendChild(ExecState *exec_state) {
             }
         }
         else if (IsString(childrens) && parent) {
-            std::string value = CStringValue(childrens);
-            if (value == "\\ue7f4") {
-                value = "\ue7f4";
-            }
-            LOGD("[VM][VNode][AppendChild]:string:%s\n", value.c_str());
-            parent->SetAttribute("value", value);
+            parent->SetAttribute("value", CStringValue(childrens));
         }
         else {
             VNode *children = reinterpret_cast<VNode *>(exec_state->GetArgument(1)->cptr);
diff --git a/weex_core/Source/core/data_render/vnode/vnode_render_manager.cc b/weex_core/Source/core/data_render/vnode/vnode_render_manager.cc
index db9bfdd4fe..cdff7efd3c 100644
--- a/weex_core/Source/core/data_render/vnode/vnode_render_manager.cc
+++ b/weex_core/Source/core/data_render/vnode/vnode_render_manager.cc
@@ -30,6 +30,7 @@
 #include "core/render/node/factory/render_creator.h"
 #include "core/bridge/platform_bridge.h"
 #include "core/data_render/binary_file.h"
+#include "core/data_render/common_error.h"
 
 #define VRENDER_LOG true
 
@@ -166,6 +167,13 @@ void VNodeRenderManager::InitVM() {
 }
 
 void VNodeRenderManager::CreatePage(const std::string &input, const std::string &page_id, const  std::string &options, const std::string &init_data) {
+    std::string err = CreatePageImpl(input, page_id, options, init_data);
+    if (!err.empty()) {
+        WeexCore::WeexCoreManager::Instance()->getPlatformBridge()->platform_side()->ReportException(page_id.c_str(), nullptr, err.c_str());
+    }
+}
+
+std::string VNodeRenderManager::CreatePageImpl(const std::string &input, const std::string &page_id, const std::string &options, const std::string &init_data) {
     InitVM();
     auto start = std::chrono::steady_clock::now();
     ExecState *exec_state = new ExecState(g_vm);
@@ -188,8 +196,8 @@ void VNodeRenderManager::CreatePage(const std::string &input, const std::string
     //auto compile_start = std::chrono::steady_clock::now();
     exec_state->Compile(err);
     if (!err.empty()) {
-      LOGE("DATA_RENDER, compile err: %s",err.c_str());
-      return;
+        LOGE("DATA_RENDER, compile err: %s",err.c_str());
+        return err;
     }
     auto compile_post = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start);
     LOGD("[DATA_RENDER], Compile time:[%lld]\n", compile_post.count());
@@ -198,15 +206,15 @@ void VNodeRenderManager::CreatePage(const std::string &input, const std::string
     exec_state->Execute(err);
     if (!err.empty()) {
         LOGE("DATA_RENDER, exec err: %s",err.c_str());
-        return;
+        return err;
     }
     if (exec_state->context()->root() == NULL) {
-        return;
+        return err;
     }
     CreatePageInternal(page_id, exec_state->context()->root());
     auto duration_post = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start);
-
     LOGD("DATA_RENDER, All time %lld\n", duration_post.count());
+    return err;
 }
     
 void VNodeRenderManager::ExecuteRegisterModules(ExecState *exec_state, std::vector<std::string>& registers) {
@@ -229,17 +237,23 @@ void VNodeRenderManager::ExecuteRegisterModules(ExecState *exec_state, std::vect
     } while (0);
 }
 
-void VNodeRenderManager::CreatePage(const char *contents, unsigned long length, const std::string& page_id, const std::string& options, const std::string& init_data) {
-    BinaryFile *file = BinaryFile::instance();
-    file->set_input(contents);
-    file->set_length(length);
+std::string VNodeRenderManager::CreatePageWithOpcode(const std::string& page_id, const std::string& options, const std::string& init_data) {
     InitVM();
     auto start = std::chrono::steady_clock::now();
     ExecState *exec_state = new ExecState(g_vm);
     exec_states_.insert({page_id, exec_state});
     VNodeExecEnv::InitCFuncEnv(exec_state);
     std::string err;
-    exec_state->startDecode();
+    try {
+        exec_state->startDecode();
+    } catch (std::exception &e) {
+        auto error = static_cast<Error *>(&e);
+        if (error) {
+            err = error->what();
+            std::cerr << error->what() << std::endl;
+        }
+        return err;
+    }
     exec_state->endDecode();
     if (init_data.length() > 0) {
         VNodeExecEnv::InitInitDataValue(exec_state, init_data);
@@ -248,14 +262,26 @@ void VNodeRenderManager::CreatePage(const char *contents, unsigned long length,
     LOGD("[DATA_RENDER], Decoder time:[%lld]\n", decoder_post.count());
     exec_state->Execute(err);
     if (!err.empty()) {
-        return;
+        return err;
     }
     if (exec_state->context()->root() == NULL) {
-        return;
+        err = "Root vonde is null";
+        return err;
     }
     CreatePageInternal(page_id, exec_state->context()->root());
     auto duration_post = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start);
     LOGD("[DATA_RENDER], All time:[%lld]\n", duration_post.count());
+    return err;
+}
+
+void VNodeRenderManager::CreatePage(const char *contents, unsigned long length, const std::string& page_id, const std::string& options, const std::string& init_data) {
+    BinaryFile *file = BinaryFile::instance();
+    file->set_input(contents);
+    file->set_length(length);
+    string err = CreatePageWithOpcode(page_id, options, init_data);
+    if (!err.empty()) {
+        WeexCore::WeexCoreManager::Instance()->getPlatformBridge()->platform_side()->ReportException(page_id.c_str(), nullptr, err.c_str());
+    }
 }
 
 bool VNodeRenderManager::RefreshPage(const std::string& page_id,
diff --git a/weex_core/Source/core/data_render/vnode/vnode_render_manager.h b/weex_core/Source/core/data_render/vnode/vnode_render_manager.h
index b309e8f5d0..351b172926 100644
--- a/weex_core/Source/core/data_render/vnode/vnode_render_manager.h
+++ b/weex_core/Source/core/data_render/vnode/vnode_render_manager.h
@@ -65,6 +65,8 @@ class VNodeRenderManager {
   bool CreatePageInternal(const std::string &page_id, VNode *v_node);
   bool RefreshPageInternal(const std::string &page_id, VNode *new_node);
   bool ClosePageInternal(const std::string &page_id);
+  std::string CreatePageWithOpcode(const std::string& page_id, const std::string& options, const std::string& init_data);
+  std::string CreatePageImpl(const std::string &input, const std::string &page_id, const std::string &options, const std::string &init_data);
 
   static VM *g_vm;
   static VNodeRenderManager *g_instance;


 

----------------------------------------------------------------
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