diff --git a/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java b/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java index 79175292fb..89a0b4f9e1 100644 --- a/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java +++ b/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java @@ -84,8 +84,8 @@ public void onCreate() { if(!TextUtils.isEmpty(BuildConfig.externalLibraryName)){ builder.addNativeLibrary(BuildConfig.externalLibraryName); } - WXSDKEngine.initialize(this, builder.build()); WXSDKManager.getInstance().setWxConfigAdapter(new DefaultConfigAdapter()); + WXSDKEngine.initialize(this, builder.build()); WXSDKManager.getInstance().addWXAnalyzer(new WXAnalyzerDemoListener()); WXAnalyzerDataTransfer.isOpenPerformance = false; diff --git a/android/sdk/build.gradle b/android/sdk/build.gradle index 68336a74ef..ff0342b690 100755 --- a/android/sdk/build.gradle +++ b/android/sdk/build.gradle @@ -117,6 +117,8 @@ android { def android_project_dir = projectDir + def buildRuntimeApi = project.hasProperty('buildRuntimeApi') ? project.property('buildRuntimeApi') : false; + defaultConfig { buildConfigField "String", "buildJavascriptFrameworkVersion", "\"${jsfmVersion}\"" buildConfigField "String", "buildVersion", "\"${version}\"" @@ -137,7 +139,8 @@ android { '-DANDROID_STL=' + "${cxx_stl}", '-DCMAKE_BUILD_TYPE=Release', '-DANDROID_PROJECT_DIR=' + "${android_project_dir}", - '-DENABLE_ASAN=false' + '-DENABLE_ASAN=false', + '-DBUILD_RUNTIME_API='+"${buildRuntimeApi}" } } } diff --git a/android/sdk/libs/armeabi-v7a/libJavaScriptCore.so b/android/sdk/libs/armeabi-v7a/libJavaScriptCore.so index 2d590993db..3cc8a8a25d 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/src/main/java/com/taobao/weex/WXEnvironment.java b/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java index 17fa0b17fa..a0a0b67018 100644 --- a/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java +++ b/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java @@ -89,6 +89,8 @@ public class WXEnvironment { public static boolean AUTO_UPDATE_APPLICATION_SCREEN_SIZE = true; + public static volatile boolean sUseRunTimeApi = false; + /** * Debug model */ @@ -137,6 +139,8 @@ public class WXEnvironment { private static String CORE_JSS_SO_PATH = null; + public static String CORE_JSS_RUNTIME_SO_PATH = null; + private static String CORE_JSS_ICU_PATH = null; private static String CORE_JSC_SO_PATH = null; @@ -528,9 +532,14 @@ public static String getLibJScRealPath() { } public static String getLibJssRealPath() { + if (WXEnvironment.sUseRunTimeApi && !TextUtils.isEmpty(CORE_JSS_RUNTIME_SO_PATH)){ + WXLogUtils.e("test-> findLibJssRuntimeRealPath " + CORE_JSS_RUNTIME_SO_PATH); + return CORE_JSS_RUNTIME_SO_PATH; + } + if(TextUtils.isEmpty(CORE_JSS_SO_PATH)) { CORE_JSS_SO_PATH = findSoPath(CORE_JSS_SO_NAME); - WXLogUtils.e("findLibJssRealPath " + CORE_JSS_SO_PATH); + WXLogUtils.e("test-> findLibJssRealPath " + CORE_JSS_SO_PATH); } return CORE_JSS_SO_PATH; diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/WXParams.java b/android/sdk/src/main/java/com/taobao/weex/bridge/WXParams.java index 657b21aafd..9b2ad2a264 100644 --- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXParams.java +++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXParams.java @@ -18,6 +18,7 @@ */ package com.taobao.weex.bridge; +import com.taobao.weex.WXEnvironment; import com.taobao.weex.base.CalledByNative; import com.taobao.weex.utils.WXLogUtils; @@ -244,6 +245,11 @@ public void setLibLdPath(String libLdPath) { this.libLdPath = libLdPath; } + @CalledByNative + public String getUseRunTimeApi() { + return String.valueOf(WXEnvironment.sUseRunTimeApi); + } + public Map toMap() { HashMap map = new HashMap<>(); map.put("appName", appName); @@ -266,6 +272,8 @@ public Map toMap() { map.put("libIcuPath", libIcuPath); map.put("libLdPath", libLdPath); map.put("options", options); + map.put("useRunTimeApi",WXEnvironment.sUseRunTimeApi); + map.put("__enable_native_promise__",!WXEnvironment.sUseRunTimeApi); return map; } } diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/WXFileUtils.java b/android/sdk/src/main/java/com/taobao/weex/utils/WXFileUtils.java index 530bea8211..82a4efab49 100644 --- a/android/sdk/src/main/java/com/taobao/weex/utils/WXFileUtils.java +++ b/android/sdk/src/main/java/com/taobao/weex/utils/WXFileUtils.java @@ -24,6 +24,7 @@ import java.io.BufferedInputStream; import java.io.BufferedReader; +import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -266,4 +267,33 @@ public static void copyFile(File oldFile, File newFile) { } } + public static void copyFileWithException(File oldFile,File newFile ) throws Exception{ + FileInputStream inputStream = null; + FileOutputStream outputStream = null; + try { + inputStream = new FileInputStream(oldFile); + byte[] data = new byte[1024]; + outputStream = new FileOutputStream(newFile); + while (inputStream.read(data) != -1) { + outputStream.write(data); + } + }catch (Exception e){ + throw e; + }finally { + closeIo(inputStream); + closeIo(outputStream); + } + } + + public static void closeIo(Closeable c){ + if (null == c){ + return; + } + try { + c.close(); + }catch (Throwable e){ + e.printStackTrace(); + } + } + } diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java b/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java index d870ef3d4c..3ca91db6b5 100644 --- a/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java +++ b/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java @@ -19,13 +19,18 @@ package com.taobao.weex.utils; import android.content.Context; +import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.os.Build; +import android.preference.PreferenceManager; import android.text.TextUtils; import android.util.Log; import com.taobao.weex.IWXStatisticsListener; import com.taobao.weex.WXEnvironment; +import com.taobao.weex.WXSDKManager; +import com.taobao.weex.adapter.IWXConfigAdapter; import com.taobao.weex.adapter.IWXSoLoaderAdapter; import com.taobao.weex.adapter.IWXUserTrackAdapter; import com.taobao.weex.common.WXErrorCode; @@ -33,6 +38,7 @@ import java.io.BufferedReader; import java.io.Closeable; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; @@ -119,6 +125,7 @@ public static boolean initSo(String libName, int version, IWXUserTrackAdapter ut // copy startup so copyStartUpSo(); + copyJssRuntimeSo(); boolean InitSuc = false; // if (checkSoIsValid(libName, BuildConfig.ARMEABI_Size) ||checkSoIsValid(libName, BuildConfig.X86_Size)) { @@ -304,6 +311,61 @@ public static void copyStartUpSo() { } } + private static void copyJssRuntimeSo(){ + Log.e("test->", "enter copyJssRuntimeSo: "); + boolean tryUseRunTimeApi = WXUtils.checkGreyConfig("wxapm","use_runtime_api","100"); + Log.e("test->", "tryUseRunTimeApi ? "+ tryUseRunTimeApi); + if (!tryUseRunTimeApi){ + return; + } + try { + Log.e("test->", "copyJssRuntimeSo: "); + Context c = WXEnvironment.getApplication(); + String pkgName = c.getPackageName(); + String toPath = "/data/data/" + pkgName + "/weex"; + String cachePath = WXEnvironment.getApplication().getApplicationContext().getCacheDir().getPath(); + if (cachePath != null && cachePath.indexOf("/cache") > 0) { + toPath = cachePath.replace("/cache", "/weex/libs"); + } + File dir = new File(toPath); + if (!dir.exists()){ + dir.mkdirs(); + } + File targetFile = new File(toPath,"libweexjss.so"); + + /** 1. check so and versionCode. if update, then rm old jss.so(runtime) in pkg/libs, and copy new so from apk **/ + String keyVersionCode = "app_version_code_weex"; + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); + PackageInfo info = c.getPackageManager().getPackageInfo(c.getPackageName(), 0); + if (targetFile.exists()){ + if (prefs.getInt(keyVersionCode,-1) < info.versionCode){ + targetFile.delete(); + }else { + WXEnvironment.CORE_JSS_RUNTIME_SO_PATH= targetFile.getAbsolutePath(); + WXEnvironment.sUseRunTimeApi = true; + Log.e("test->", "copyJssRuntimeSo: return"); + return; + } + } + /** 2. copy jss(runtime) so **/ + String fromPath = ((PathClassLoader) (WXSoInstallMgrSdk.class.getClassLoader())).findLibrary("weexjssr"); + if (TextUtils.isEmpty(fromPath)){ + return; + } + targetFile.createNewFile(); + WXFileUtils.copyFileWithException(new File(fromPath),targetFile); + /**3. update flag **/ + WXEnvironment.CORE_JSS_RUNTIME_SO_PATH= targetFile.getAbsolutePath(); + prefs.edit().putInt(keyVersionCode,info.versionCode).apply(); + WXEnvironment.sUseRunTimeApi = true; + Log.e("test->", "copyJssRuntimeSo: return 2"); + }catch (Throwable e){ + e.printStackTrace(); + WXEnvironment.sUseRunTimeApi = false; + Log.e("test->", "copyJssRuntimeSo: exception" + e); + } + } + private static String _getFieldReflectively(Build build, String fieldName) { try { final Field field = Build.class.getField(fieldName); diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/WXUtils.java b/android/sdk/src/main/java/com/taobao/weex/utils/WXUtils.java index 1ec02465c7..a024714995 100644 --- a/android/sdk/src/main/java/com/taobao/weex/utils/WXUtils.java +++ b/android/sdk/src/main/java/com/taobao/weex/utils/WXUtils.java @@ -26,7 +26,10 @@ import android.support.annotation.Nullable; import android.support.v4.util.LruCache; import android.text.TextUtils; +import android.util.Log; import com.taobao.weex.WXEnvironment; +import com.taobao.weex.WXSDKManager; +import com.taobao.weex.adapter.IWXConfigAdapter; import com.taobao.weex.common.Constants; import com.taobao.weex.common.WXConfig; @@ -569,6 +572,25 @@ public static int getNumberInt(Object value, int defaultValue){ }catch (Exception e){return defaultValue;} } + public static boolean checkGreyConfig(String group,String key,String defaultValue){ + Log.e("test->", "enter checkGreyConfig"); + IWXConfigAdapter configAdapter = WXSDKManager.getInstance().getWxConfigAdapter(); + if (null == configAdapter) { + Log.e("test->", "checkGreyConfig: configAdapter return false"); + return false; + } + double randomValue = Math.random() * 100; + double max = 100; + try { + String configValue = configAdapter.getConfig(group, key, defaultValue); + max = Double.valueOf(configValue); + } catch (Exception e) { + e.printStackTrace(); + } + Log.e("test->", "checkGreyConfig: "+ randomValue +", max:"+max); + return randomValue < max; + } + private static final long sInterval = System.currentTimeMillis() - SystemClock.uptimeMillis(); public static long getFixUnixTime(){ diff --git a/weex_core/Source/CMakeLists.txt b/weex_core/Source/CMakeLists.txt index 22d8edc299..273a77e238 100644 --- a/weex_core/Source/CMakeLists.txt +++ b/weex_core/Source/CMakeLists.txt @@ -88,6 +88,7 @@ set(COMMON_SRCS ./core/bridge/platform/core_side_in_platform.cpp ./core/bridge/script/core_side_in_script.cpp ./core/parser/dom_wson.cpp + ./core/parser/action_args_check.cpp ./core/network/http_module.cc ) @@ -106,7 +107,20 @@ if(ANDROID) add_definitions(-DOS_ANDROID=1) ## add_subdirectory for subdirectory has a CMakeLists.txt add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/third_party/IPC) - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/android/jsengine) + + + message("check build jsc BUILD_RUNTIME_API flag: ${BUILD_RUNTIME_API}") + if ("${BUILD_RUNTIME_API}" STREQUAL "true") + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/js_runtime) + message("cmake build jsApi for runtime") + else() + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/android/jsengine) + message("cmake build jsApi for jsc") + endif() + + + + ## include_directories for include head file include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/IPC) 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 index 4590ebb895..6c0f0d818a 100644 --- 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 @@ -319,10 +319,15 @@ namespace weex { // } if (result->getType() != IPCType::VOID) { if (result->getStringLength() > 0) { +#ifdef USE_JS_RUNTIME + return jString2String(result->getStringContent(), + result->getStringLength()).c_str(); +#else return jString2String(result->getStringContent(), result->getStringLength()) .utf8() .data(); +#endif } } } catch (IPCException &e) { @@ -391,10 +396,15 @@ namespace weex { // } if (result->getType() != IPCType::VOID) { if (result->getStringLength() > 0) { +#ifdef USE_JS_RUNTIME + return jString2String(result->getStringContent(), + result->getStringLength()).c_str(); +#else return jString2String(result->getStringContent(), result->getStringLength()) .utf8() .data(); +#endif } } return nullptr; 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 index 368b21dfa3..255328a7d1 100644 --- 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 @@ -27,6 +27,8 @@ #include "core/manager/weex_core_manager.h" #include "core/render/manager/render_manager.h" #include "third_party/IPC/IPCResult.h" +#include "core/config/core_environment.h" +#include "core/parser/action_args_check.h" namespace weex { namespace bridge { @@ -38,6 +40,19 @@ CoreSideInSimple::~CoreSideInSimple() {} void CoreSideInSimple::CallNative(const char *page_id, const char *task, const char *callback) { if (page_id == nullptr || task == nullptr) return; + + if (WXCoreEnvironment::getInstance()->isUseRunTimeApi()){ + if (isCallNativeToFinish(task)){ + RenderManager::GetInstance()->CreateFinish(page_id); + } else { + WeexCoreManager::Instance() + ->getPlatformBridge() + ->platform_side() + ->CallNative(page_id, task, callback); + } + return; + } + if (strcmp( task, "[{\"module\":\"dom\",\"method\":\"createFinish\",\"args\":[]}]") == 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 index 7b19f389c9..b9b03c2f76 100644 --- 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 @@ -255,8 +255,13 @@ namespace weex { init_framework_params->value = IPCByteArrayToWeexByteArray(ba); if(!WeexEnv::getEnv()->enableBackupThread()) { +#ifdef USE_JS_RUNTIME + std::string type = init_framework_params->type->content; + std::string value = init_framework_params->value->content; +#else auto type = String::fromUTF8(init_framework_params->type->content); auto value = String::fromUTF8(init_framework_params->value->content); +#endif if(type == "enableBackupThread") { auto enable = value == "true"; LOGE("enable backupThread %d",enable); 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 index 7aa9e59b5f..d71ca769bf 100644 --- 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 @@ -24,7 +24,11 @@ #define WEEXV8_SCRIPT_SIDE_IN_QUEUE_H #include "core/bridge/script_bridge.h" +#ifdef USE_JS_RUNTIME +#include "js_runtime/weex/task/weex_task_queue.h" +#else #include "android/jsengine/task/weex_task_queue.h" +#endif namespace weex { namespace bridge { diff --git a/weex_core/Source/android/jsengine/object/args.cpp b/weex_core/Source/android/jsengine/object/args.cpp index e6c9f453d0..5a5b3329d8 100644 --- a/weex_core/Source/android/jsengine/object/args.cpp +++ b/weex_core/Source/android/jsengine/object/args.cpp @@ -16,7 +16,11 @@ * specific language governing permissions and limitations * under the License. */ +#ifdef USE_JS_RUNTIME +#include "js_runtime/weex/object/args.h" +#else #include "android/jsengine/object/args.h" +#endif namespace WeexCore{ diff --git a/weex_core/Source/android/jsengine/object/args.h b/weex_core/Source/android/jsengine/object/args.h index e0586863fb..dcf2852bbb 100644 --- a/weex_core/Source/android/jsengine/object/args.h +++ b/weex_core/Source/android/jsengine/object/args.h @@ -20,12 +20,15 @@ // Created by jianbai.gbj on 15/05/2018. // +#ifdef USE_JS_RUNTIME +#include "js_runtime/weex/object/args.h" +#else + #ifndef ARGS_H #define ARGS_H #include #include - #include "wson/wson.h" /** @@ -87,3 +90,4 @@ namespace WeexCore { }; #endif +#endif //USE_JS_RUNTIME diff --git a/weex_core/Source/android/jsengine/object/args/exe_js_args.cpp b/weex_core/Source/android/jsengine/object/args/exe_js_args.cpp index 6c5041bc34..ec54eb6873 100644 --- a/weex_core/Source/android/jsengine/object/args/exe_js_args.cpp +++ b/weex_core/Source/android/jsengine/object/args/exe_js_args.cpp @@ -101,7 +101,7 @@ VALUE_WITH_TYPE *ExeJsArgs::copyValueToSelf(VALUE_WITH_TYPE *value_with_type) { pType->value.string = genWeexStringSS(value_with_type->value.string->content, value_with_type->value.string->length); - const String &string = weexString2String(pType->value.string); + // const String &string = weexString2String(pType->value.string); } break; diff --git a/weex_core/Source/android/jsengine/object/args/init_framework_args.h b/weex_core/Source/android/jsengine/object/args/init_framework_args.h index 030a43c00b..261680cf7b 100644 --- a/weex_core/Source/android/jsengine/object/args/init_framework_args.h +++ b/weex_core/Source/android/jsengine/object/args/init_framework_args.h @@ -25,7 +25,9 @@ #include #include "include/WeexApiHeader.h" +#ifndef USE_JS_RUNTIME #include "include/wtf/text/WTFString.h" +#endif #include "third_party/IPC/IPCArguments.h" class InitFrameworkArgs { diff --git a/weex_core/Source/android/jsengine/object/weex_env.cpp b/weex_core/Source/android/jsengine/object/weex_env.cpp index 755f926e45..386373e067 100644 --- a/weex_core/Source/android/jsengine/object/weex_env.cpp +++ b/weex_core/Source/android/jsengine/object/weex_env.cpp @@ -21,6 +21,7 @@ // #include "weex_env.h" +//#include "android/jsengine/wson/wson_jsc.h" WeexEnv *WeexEnv::env_ = nullptr; @@ -52,6 +53,7 @@ void WeexEnv::initJSC(bool isMultiProgress) { // return false; } +#ifndef USE_JS_RUNTIME Options::enableRestrictedOptions(true); // Initialize JSC before getting VM. WTF::initializeMainThread(); @@ -59,6 +61,7 @@ void WeexEnv::initJSC(bool isMultiProgress) { JSC::initializeThreading(); #if ENABLE(WEBASSEMBLY) JSC::Wasm::enableFastMemory(); +#endif #endif }); } @@ -80,5 +83,7 @@ void WeexEnv::set_m_cache_task_(volatile bool m_cache_task_) { WeexEnv::m_cache_task_ = m_cache_task_; } WeexEnv::~WeexEnv() { +#ifndef USE_JS_RUNTIME wson::destory(); +#endif } diff --git a/weex_core/Source/android/jsengine/object/weex_env.h b/weex_core/Source/android/jsengine/object/weex_env.h index 86e851d508..3d1cc80e5e 100644 --- a/weex_core/Source/android/jsengine/object/weex_env.h +++ b/weex_core/Source/android/jsengine/object/weex_env.h @@ -24,10 +24,20 @@ #define WEEXV8_WEEXENV_H #include + +#ifdef USE_JS_RUNTIME +#include "js_runtime/weex/task/weex_task.h" +#include "js_runtime/weex/task/back_to_weex_core_queue.h" +#include "js_runtime/weex/task/timer_queue.h" +#include "base/crash/crash_handler.h" + +#else #include #include "android/jsengine/task/back_to_weex_core_queue.h" - #include "android/jsengine/task/timer_queue.h" +#endif + + #include "android/jsengine/weex_ipc_server.h" #include "android/jsengine/weex_ipc_client.h" diff --git a/weex_core/Source/android/jsengine/object/weex_global_object.cpp b/weex_core/Source/android/jsengine/object/weex_global_object.cpp index 3345962831..436805c621 100644 --- a/weex_core/Source/android/jsengine/object/weex_global_object.cpp +++ b/weex_core/Source/android/jsengine/object/weex_global_object.cpp @@ -191,6 +191,7 @@ void WeexGlobalObject::initWxEnvironment(std::vector &p // add for debug mode if (String("debugMode") == type && String("true") == value) { WeexCore::DebugMode = true; + LOGE("jss use %s"," jsc"); } // -------------------------------------------------------- diff --git a/weex_core/Source/android/jsengine/weex_ipc_server.cpp b/weex_core/Source/android/jsengine/weex_ipc_server.cpp index 7b663999ce..8e09a6f366 100644 --- a/weex_core/Source/android/jsengine/weex_ipc_server.cpp +++ b/weex_core/Source/android/jsengine/weex_ipc_server.cpp @@ -24,10 +24,16 @@ #include "android/jsengine/weex_runtime.h" #include "core/manager/weex_core_manager.h" #include "android/jsengine/weex_jsc_utils.h" +#ifdef USE_JS_RUNTIME +#include "base/crash/crash_handler.h" +#include +#include +//using namespace crash_handler; +#else using namespace JSC; using namespace WTF; using namespace WEEXICU; - +#endif struct WeexJSServer::WeexJSServerImpl { WeexJSServerImpl(int serverFd, int clientFd, bool enableTrace, std::string crashFileName); diff --git a/weex_core/Source/android/jsengine/weex_jsc_utils.h b/weex_core/Source/android/jsengine/weex_jsc_utils.h index a55e597a1d..216d560cea 100644 --- a/weex_core/Source/android/jsengine/weex_jsc_utils.h +++ b/weex_core/Source/android/jsengine/weex_jsc_utils.h @@ -20,6 +20,10 @@ // Created by Darin on 11/02/2018. // +#ifdef USE_JS_RUNTIME +#include "js_runtime/weex/utils/weex_jsc_utils.h" +#else + #ifndef WEEXV8_UTILS_H #define WEEXV8_UTILS_H @@ -343,3 +347,4 @@ namespace WEEXICU { } #endif //WEEXV8_UTILS_H +#endif //USE_JS_RUNTIME diff --git a/weex_core/Source/android/jsengine/weex_runtime.h b/weex_core/Source/android/jsengine/weex_runtime.h index 5c38d87f2d..f15dcd0072 100644 --- a/weex_core/Source/android/jsengine/weex_runtime.h +++ b/weex_core/Source/android/jsengine/weex_runtime.h @@ -20,6 +20,10 @@ // Created by Darin on 28/04/2018. // +#ifdef USE_JS_RUNTIME +#include "js_runtime/weex/object/weex_runtime.h" +#else + #ifndef WEEXV8_JSRUNTIME_H #define WEEXV8_JSRUNTIME_H @@ -119,3 +123,4 @@ class WeexRuntime { #endif //WEEXV8_JSRUNTIME_H +#endif //USE_JS_RUNTIME diff --git a/weex_core/Source/android/utils/params_utils.cpp b/weex_core/Source/android/utils/params_utils.cpp index 38a7c68f51..ef401d8646 100644 --- a/weex_core/Source/android/utils/params_utils.cpp +++ b/weex_core/Source/android/utils/params_utils.cpp @@ -203,6 +203,24 @@ std::vector initFromParam( } } + jmethodID m_use_runtime_api = env->GetMethodID(c_params, "getUseRunTimeApi", "()Ljava/lang/String;"); + if (m_use_runtime_api == nullptr) { + LOGE("m_use_runtime_api method is missing"); + WXCoreEnvironment::getInstance()->setUseRunTimeApi(false); + } else { + jobject j_use_runtime_api = + env->CallObjectMethod(params, m_use_runtime_api); + const char* use_runtime_api_str = + env->GetStringUTFChars((jstring)(j_use_runtime_api), nullptr); + if (nullptr == use_runtime_api_str){ + WXCoreEnvironment::getInstance()->setUseRunTimeApi(false); + } else{ + bool use_runtime_api = strstr(use_runtime_api_str, "true") != nullptr; + WXCoreEnvironment::getInstance()->setUseRunTimeApi(use_runtime_api); + env->DeleteLocalRef(j_use_runtime_api); + } + } + jmethodID m_get_jsc_so_path = env->GetMethodID(c_params, "getLibJscPath", "()Ljava/lang/String;"); if (m_get_jsc_so_path != nullptr) { diff --git a/weex_core/Source/core/bridge/script/core_side_in_script.cpp b/weex_core/Source/core/bridge/script/core_side_in_script.cpp index 4bb6e44eae..e8cc3db9a3 100644 --- a/weex_core/Source/core/bridge/script/core_side_in_script.cpp +++ b/weex_core/Source/core/bridge/script/core_side_in_script.cpp @@ -27,6 +27,8 @@ #include "core/render/manager/render_manager.h" #include "core/bridge/eagle_bridge.h" #include "wson/wson_parser.h" +#include "core/config/core_environment.h" +#include "core/parser/action_args_check.h" #ifdef OS_ANDROID #include #include "android/weex_extend_js_api.h" @@ -52,6 +54,17 @@ void CoreSideInScript::CallNative(const char *page_id, const char *task, const char *callback) { if (page_id == nullptr || task == nullptr) return; + if (WXCoreEnvironment::getInstance()->isUseRunTimeApi()){ + if (isCallNativeToFinish(task)){ + RenderManager::GetInstance()->CreateFinish(page_id); + } else { + WeexCoreManager::Instance() + ->getPlatformBridge() + ->platform_side() + ->CallNative(page_id, task, callback); + } + return; + } std::string task_str(task); std::string target_str("[{\"module\":\"dom\",\"method\":\"createFinish\"," "\"args\":[]}]"); diff --git a/weex_core/Source/core/config/core_environment.cpp b/weex_core/Source/core/config/core_environment.cpp index 2b89c22e2a..57980ba53a 100644 --- a/weex_core/Source/core/config/core_environment.cpp +++ b/weex_core/Source/core/config/core_environment.cpp @@ -96,4 +96,12 @@ namespace WeexCore { it->second = value; } } + + void WXCoreEnvironment::setUseRunTimeApi(bool useRuntimeApi) { + this->mUseRuntimeApi = useRuntimeApi; + } + + bool WXCoreEnvironment::isUseRunTimeApi(){ + return mUseRuntimeApi; + } } diff --git a/weex_core/Source/core/config/core_environment.h b/weex_core/Source/core/config/core_environment.h index 1ebf53935c..0d4ea0627f 100644 --- a/weex_core/Source/core/config/core_environment.h +++ b/weex_core/Source/core/config/core_environment.h @@ -56,6 +56,8 @@ namespace WeexCore { bool mInteractionLogSwitch; + bool mUseRuntimeApi; + public: bool SetPlatform(std::string platformName); @@ -94,6 +96,10 @@ namespace WeexCore { return mOptions; }; + bool isUseRunTimeApi(); + + void setUseRunTimeApi(bool useRuntimeApi); + void AddOption(std::string key, std::string value); void PutOption(std::string key, std::string value); diff --git a/weex_core/Source/core/parser/action_args_check.cpp b/weex_core/Source/core/parser/action_args_check.cpp new file mode 100644 index 0000000000..10643f503f --- /dev/null +++ b/weex_core/Source/core/parser/action_args_check.cpp @@ -0,0 +1,59 @@ +/** + * 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 陈佩翰 on 2019/3/8. +// + +#include "action_args_check.h" +#include "third_party/json11/json11.hpp" +#include "base/utils/log_utils.h" + +namespace WeexCore { + bool isCallNativeToFinish(const char *task) { + if (nullptr == task) { + return false; + } + //try match json str:[{"args": [], "method": "createFinish", "module": "dom"}] + std::string task_str(task); + if (task_str.length() != 57) { + return false; + } + + std::string errr; + json11::Json task_json = json11::Json::parse(task_str, errr); + if (!task_json.is_array() || task_json.array_items().size() <= 0) { + return false; + } + auto array = task_json.array_items(); + auto item = array[0]; + if (!array[0].is_object()) { + return false; + } + auto module_value = item["module"]; + auto method_value = item["method"]; + auto args_value = item["args"]; + + bool isCreateFinishAction = false; + if (module_value.is_string() && method_value.is_string() && args_value.is_array()) { + isCreateFinishAction = module_value.dump() == "\"dom\"" && method_value.dump() == "\"createFinish\"" && + args_value.array_items().size() <= 0; + } + return isCreateFinishAction; + } +} diff --git a/weex_core/Source/core/parser/action_args_check.h b/weex_core/Source/core/parser/action_args_check.h new file mode 100644 index 0000000000..94cabf57be --- /dev/null +++ b/weex_core/Source/core/parser/action_args_check.h @@ -0,0 +1,31 @@ +/** + * 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 陈佩翰 on 2019/3/8. +// + +#ifndef PROJECT_ACTION_ARGS_CHECK_H +#define PROJECT_ACTION_ARGS_CHECK_H + +namespace WeexCore { + bool isCallNativeToFinish(const char* task); +} + + +#endif //PROJECT_ACTION_ARGS_CHECK_H diff --git a/weex_core/Source/core/parser/dom_wson.cpp b/weex_core/Source/core/parser/dom_wson.cpp index f587654c95..a73d8e3580 100644 --- a/weex_core/Source/core/parser/dom_wson.cpp +++ b/weex_core/Source/core/parser/dom_wson.cpp @@ -20,12 +20,21 @@ // Created by furture on 2018/5/15. // +#include +#include #include "core/render/node/render_object.h" #include "core/render/page/render_page.h" #include "core/render/node/factory/render_creator.h" #include "dom_wson.h" #include "wson/wson.h" #include "wson/wson_parser.h" +//#ifdef test_log +#include "base/utils/log_utils.h" +#include "core/config/core_environment.h" +//#else +//#define LOGW +//#define LOGE +//#endif namespace WeexCore { @@ -59,7 +68,7 @@ namespace WeexCore { for(int i=0; i < size; i++){ std::string objectKey = parser.nextMapKeyUTF8(); if(0 == strcmp(objectKey.c_str(), "ref")){ - ref = parser.nextStringUTF8(parser.nextType()); + ref = parser.nextStringUTF8(parser.nextType()); if (render != nullptr) { // ref may be after type, so need set to render render->set_ref(ref); @@ -196,12 +205,132 @@ namespace WeexCore { } - RenderObject *Wson2RenderObject(const char *data, const std::string &pageId, bool reserveStyles){ + + RenderObject *parserWson2RenderObjectNew(wson_parser& parser, RenderObject *parent, int index, const std::string &pageId,bool reserveStyles){ + int objectType = parser.nextType(); + if(!parser.isMap(objectType)){ + parser.skipValue(objectType); + return nullptr; + } + + /** + * because strem key order specified, so will cann't dependecy it's keys order, + * if key orders right parse one time, if not first parse ref type create render object + * then parse others attrs + * */ + int size = parser.nextMapSize(); + std::string ref; + std::string renderType; + std::map attrs; + std::map styles; + std::vector events; + std::vector childrens; + + RenderObject *render = nullptr; + for(int i=0; i < size; i++){ + std::string objectKey = parser.nextMapKeyUTF8(); + if(0 == strcmp(objectKey.c_str(), "ref")){ + ref = parser.nextStringUTF8(parser.nextType()); + }else if (0 == strcmp(objectKey.c_str(), "type")) { + renderType = parser.nextStringUTF8(parser.nextType()); + }else if (0 == strcmp(objectKey.c_str(), "attr")){ //attr is map object + uint8_t attrType = parser.nextType(); + if(parser.isMap(attrType)){ + int attrMapSize = parser.nextMapSize(); + for(int attrIndex=0; attrIndex 0){ + events.push_back(eventValue); + } + } + }else{ + parser.skipValue(eventType); + } + }else if (0 == strcmp(objectKey.c_str(), "children")) { + uint8_t childType = parser.nextType(); + if(parser.isArray(childType)){ + int childSize = parser.nextArraySize(); + for(int childIndex=0; childIndex < childSize; childIndex++){ + RenderObject* child = parserWson2RenderObjectNew(parser, nullptr, childIndex, pageId,reserveStyles); + if(child != nullptr){ + childrens.push_back(child); + } + } + }else{ + parser.skipValue(childType); + } + }else{ + parser.skipValue(parser.nextType()); + } + } + + render = (RenderObject *) RenderCreator::GetInstance()->CreateRender(renderType, ref); + render->set_page_id(pageId); + + + for(auto& it : attrs){ + render->AddAttr(it.first, it.second); + } + + for(auto& it : styles){ + render->AddStyle(it.first, it.second,reserveStyles); + } + + for(auto& it : events){ + render->AddEvent(it); + } + + int childIndex = 0; + for(auto& child : childrens){ + render->AddRenderObject(childIndex, child); + childIndex++; + } + + + if (render != nullptr) { + render->ApplyDefaultStyle(reserveStyles); + render->ApplyDefaultAttr(); + } + return render; + } + + + RenderObject *Wson2RenderObject(const char *data, const std::string &pageId,bool reserveStyles){ if(!data){ return nullptr; } wson_parser parser(data); - return parserWson2RenderObject(parser, nullptr, 0, pageId, reserveStyles); + RenderObject* res; + if (WXCoreEnvironment::getInstance()->isUseRunTimeApi()){ + res= parserWson2RenderObjectNew(parser,nullptr,0,pageId,reserveStyles); + } else{ + res= parserWson2RenderObject(parser, nullptr, 0, pageId,reserveStyles); + } + return res; } std::vector> *Wson2Pairs(const char *data){ diff --git a/weex_core/Source/js_runtime/CMakeLists.txt b/weex_core/Source/js_runtime/CMakeLists.txt new file mode 100644 index 0000000000..42bd160845 --- /dev/null +++ b/weex_core/Source/js_runtime/CMakeLists.txt @@ -0,0 +1,290 @@ +# +# 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.3) +#if (POLICY CMP0042) +# cmake_policy(SET CMP0042 NEW) +#endif () + +cmake_minimum_required(VERSION 3.4.1) + +if(DEFINED ENV{WEEX_CORE_SOURCE_DIR}) + message('WEEX_CORE_SOURCE_DIR has set') +else() +# message("rewrite WEEX_CORE_SOURCE_DIR before ${WEEX_CORE_SOURCE_DIR}") +# set(WEEX_CORE_SOURCE_DIR ../) +endif() + + +if(DEFINED ENV{ANDROID_PLATFORM}) + message('ANDROID_PLATFORM has set') +else() + message('rewrite ANDROID_PLATFORM') + set(ANDROID_PLATFORM " ") +endif() + + +set(PORT JSCOnly) +add_definitions(-DPRINT_LOG_CACHEFILE=0) +add_definitions(-DOS_ANDROID) + +# log switch for debug in file "js_runtime/utils/log_utils.h" +#add_definitions(-DLOG_JS_RUNTIME_DEBUG=1) +#add_definitions(-DLOG_WEEX_RUNTIME_DEBUG=1) +#add_definitions(-DLOG_CONVERSION_DEBUG=0) +#add_definitions(-DLOG_WEEX_BINDING_DEBUG=1) +add_definitions(-DLOG_JS_DEBUG=0) +add_definitions(-DUSE_JS_RUNTIME=1) + + +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) +elseif("${ANDROID_ABI}" STREQUAL "arm64-v8a") + add_definitions(-DWTF_CPU_ARM64) + set(WTF_CPU_ARM64 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/ForwardingHeaders) + + + + + + +set(JS_RUNTIME_API_SRCS + ${WEEX_CORE_SOURCE_DIR}/js_runtime/runtime/runtime_vm.cc + ${WEEX_CORE_SOURCE_DIR}/js_runtime/runtime/runtime_context_android.cc + ${WEEX_CORE_SOURCE_DIR}/js_runtime/runtime/runtime_values.cc + ${WEEX_CORE_SOURCE_DIR}/js_runtime/runtime/binding_macro.h + ${WEEX_CORE_SOURCE_DIR}/js_runtime/runtime/jsc/engine_context_jsc.cc + ${WEEX_CORE_SOURCE_DIR}/js_runtime/runtime/jsc/jsc_utils.cc + ${WEEX_CORE_SOURCE_DIR}/js_runtime/runtime/jsc/runtime_object_jsc.cc + ${WEEX_CORE_SOURCE_DIR}/js_runtime/runtime/jsc/runtime_values_jsc.cc + ${WEEX_CORE_SOURCE_DIR}/js_runtime/runtime/jsc/vm_jsc.cc + ${WEEX_CORE_SOURCE_DIR}/js_runtime/runtime/jsc/binding_macro_jsc.h + ${WEEX_CORE_SOURCE_DIR}/js_runtime/runtime/js_runtime_conversion.cpp + ${WEEX_CORE_SOURCE_DIR}/js_runtime/runtime/js_runtime_conversion.h + ${WEEX_CORE_SOURCE_DIR}/js_runtime/utils/log_utils.h + ) +set(WEEX_BINDING + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/binding/weex_instance_binding.cpp + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/binding/weex_instance_binding.h + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/binding/weex_global_binding.cpp + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/binding/weex_global_binding.h + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/binding/app_context_binding.cpp + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/binding/app_context_binding.h + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/binding/weex_console_binding.cpp + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/binding/weex_console_binding.h + + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/utils/wson_for_runtime.cpp + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/utils/wson_for_runtime.h + + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/binding/weex_binding_utils.cpp + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/binding/weex_binding_utils.h + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/utils/weex_conversion_utils.cpp + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/utils/weex_conversion_utils.h + + ) + +set(JSON_SRC + ${WEEX_CORE_SOURCE_DIR}/third_party/json11/json11.hpp + ${WEEX_CORE_SOURCE_DIR}/third_party/json11/json11.cc + ) +set(WEEX_RUNTIME_V2 + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/object/weex_runtime_v2.cpp + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/object/weex_runtime_v2.h + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/object/weex_object_holder_v2.cpp + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/object/weex_object_holder_v2.h + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/object/weex_global_object_v2.cpp + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/object/weex_global_object_v2.h + ) + + + + +set(${WEEXJSSERVER_NAME}_SOURCES + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/weex_ipc_client.h + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/weex_ipc_client.cpp + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/weex_ipc_server.h + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/weex_ipc_server.cpp + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/utils/weex_jsc_utils.h + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/utils/weex_jsc_utils.cpp + + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/bridge/script/script_side_in_simple.cpp + ${WEEX_CORE_SOURCE_DIR}/js_runtime/weex/bridge/script/script_side_in_queue.cpp + + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/bridge/script/script_bridge_in_multi_so.cpp + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/bridge/script/script_bridge_in_multi_process.cpp + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/bridge/script/core_side_in_multi_so.cpp + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/bridge/script/core_side_in_multi_process.cpp + #${WEEX_CORE_SOURCE_DIR}/android/jsengine/bridge/script/script_side_in_simple.cpp + #${WEEX_CORE_SOURCE_DIR}/android/jsengine/bridge/script/script_side_in_queue.cpp + + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/object/args/exe_js_args.cpp + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/object/args/init_framework_args.cpp + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/object/args.h + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/object/args.cpp + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/object/weex_env.h + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/object/weex_env.cpp + + weex/task/impl/init_framework_task.cpp + weex/task/impl/create_app_context_task.cpp + weex/task/impl/create_instance_task.cpp + weex/task/impl/call_js_on_app_context_task.cpp + weex/task/impl/destory_app_context_task.cpp + weex/task/impl/destory_instance_task.cpp + weex/task/impl/exe_js_on_app_with_result.cpp + weex/task/impl/update_global_config_task.cpp + weex/task/impl/ctime_callback_task.cpp + weex/task/impl/exe_js_services_task.cpp + weex/task/impl/exe_js_on_instance_task.cpp + weex/task/impl/exe_js_task.cpp + weex/task/impl/take_heap_snapshot.cpp + weex/task/impl/native_timer_task.cpp + weex/task/impl/update_init_framework_params_task.cpp + weex/task/weex_task.cpp + weex/task/weex_task_queue.cpp + weex/task/timer_task.cpp + weex/task/timer_queue.cpp + weex/task/back_to_weex_core_queue.cpp + + # ${JS_RUNTIME_API_SRCS} + ${JS_RUNTIME_API_SRCS} + ${DOM_API_SRCS} + ${WEEX_BINDING} + ${JSON_SRC} + ${WEEX_RUNTIME_V2} +) +link_directories(${LOCAL_LIBRARIES_DIR}) +message("LOCAL_LIBRARIES_DIR:"${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(${WEEXJSSERVER_NAME}_LIBRARY_TYPE SHARED) + +message("${LOCAL_LIBRARIES_DIR}") +set(${WEEXJSSERVER_NAME}_LIBRARIES +weexbase +weexipc +wson +#c++_shared +JavaScriptCore +WTF +#jsc +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=${WEEX_CORE_SOURCE_DIR}/android/jsengine/weexjsserver_version_script.txt -Wl,--no-undefined -Wl,-soname,libweexjss${SERVERSUFFIX}.so" +) + +#add_custom_command( +# TARGET ${WEEXJSSERVER_NAME} +# POST_BUILD +# COMMAND cp $ ${CMAKE_SOURCE_DIR}/libweexjss${SERVERSUFFIX}.so +# VERBATIM +#) + +#add_custom_command( +# TARGET ${WEEXJSSERVERSTUB_NAME} +# POST_BUILD +# COMMAND cp $ ${CMAKE_SOURCE_DIR}/libweexjsb${SERVERSUFFIX}.so +# VERBATIM +#) + +# Compile libweexjsb.so +set(WEEXJSSERVERSTUB_NAME libweexjsb.so) +add_executable(${WEEXJSSERVERSTUB_NAME} + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/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() + +# Compile libweexjst.so +set(WEEXJSSERVERSTUB_NAME_BELOW_L libweexjst.so) +add_executable(${WEEXJSSERVERSTUB_NAME_BELOW_L} + ${WEEX_CORE_SOURCE_DIR}/android/jsengine/weex_js_server_main_stub.cpp) + +target_link_libraries(${WEEXJSSERVERSTUB_NAME_BELOW_L} +${WEEXJSSERVER_NAME} +) + +if (APPLE) +set_target_properties(${WEEXJSSERVERSTUB_NAME_BELOW_L} +PROPERTIES LINK_FLAGS +"-Wl,--entry=_start" +) +endif() \ No newline at end of file diff --git a/weex_core/Source/js_runtime/runtime/base.h b/weex_core/Source/js_runtime/runtime/base.h new file mode 100644 index 0000000000..c0a749dfe2 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/base.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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_BASE_H_ +#define FLUTTER_UNICORN_RUNTIME_BASE_H_ + +#if defined(USE_V8) +#include "js_runtime/runtime/v8/v8_base.h" +#else +#include "js_runtime/runtime/jsc/jsc_base.h" +#endif + +#endif // FLUTTER_UNICORN_RUNTIME_BASE_H_ diff --git a/weex_core/Source/js_runtime/runtime/binding_macro.h b/weex_core/Source/js_runtime/runtime/binding_macro.h new file mode 100644 index 0000000000..09de412c37 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/binding_macro.h @@ -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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_BINDING_MACRO_H_ +#define FLUTTER_UNICORN_RUNTIME_BINDING_MACRO_H_ + +#if defined(USE_V8) +#include "js_runtime/runtime/v8/binding_macro_v8.h" +#else +#include "js_runtime/runtime/jsc/binding_macro_jsc.h" + +#endif + +#endif // FLUTTER_UNICORN_RUNTIME_BINDING_MACRO_H_ diff --git a/weex_core/Source/js_runtime/runtime/engine_context.h b/weex_core/Source/js_runtime/runtime/engine_context.h new file mode 100644 index 0000000000..dd2f1f5ed0 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/engine_context.h @@ -0,0 +1,115 @@ +/** + * 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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_ENGINE_CONTEXT_H_ +#define FLUTTER_UNICORN_RUNTIME_ENGINE_CONTEXT_H_ + +#include +#include +#include +#include "js_runtime/runtime/runtime_values.h" + +namespace unicorn { + class RuntimeVM; + + class EngineContextDelegate { + public: + virtual void OnEngineContextInitialized() = 0; + + virtual void OnEngineContextFinalized() = 0; + }; + + class EngineContext { + public: + static EngineContext *CreateEngineContext(EngineContextDelegate *delegate, + RuntimeVM *vm, JSRunTimeClass globalClass); + + virtual ~EngineContext() {} + + virtual void InitializeContext(JSRunTimeClass globalObjectClass) = 0; + + virtual void SetName(const std::string& name) = 0; + + virtual std::string GetName() = 0; + + virtual JSRunTimeObject GetGlobalObjectInContext() =0; + + virtual void BindDataToObject(JSRunTimeObject targetObj,void* data) = 0; + + virtual void removeObjectBindData(JSRunTimeObject targetObj) = 0; + + virtual bool RunJavaScript(const std::string &script, std::string *exception) = 0; + + virtual ScopeValues RunJavaScriptWithResult(const std::string &script, std::string *exception) = 0; + + virtual JSRunTimeValue + callJavaScriptFunc(RuntimeObject *target, const std::string &name, std::vector &args, + std::string *exception) = 0; + + virtual ScopeValues + CallJavaScriptFuncWithRuntimeValue(RuntimeObject *target, const std::string &name, std::vector &args, + std::string *exception) = 0; + + virtual void ThrowJSError(const std::string &error) = 0; + + virtual void ThrowException(const std::string &error) = 0; + + virtual void *GetContext() const { return nullptr; } + + virtual void SetGlobalPropertyValue(const std::string &property_id, ScopeValues value) = 0; + + virtual ScopeValues GetGlobalProperty(std::string property_id) = 0; + + virtual JSRunTimeValue GetPropertyValueFromObject(std::string property_id, JSRunTimeObject object) = 0; + + virtual bool GetObjectPropertyNameArray(JSRunTimeObject object,std::vector &nameArrays) = 0; + + virtual bool setObjectValue(JSRunTimeObject targetObject, const std::string &key, JSRunTimeValue value) = 0; + + /** + * @abstract The JSObject whose prototype you want to set. + * @param target the object you want change Prototype, if null,use globalObject + * @param value JSValue to set as the object's prototype. if null,use globalObjectValue + * @return success or false + */ + virtual bool SetObjectPrototypeFromValue(JSRunTimeObject target, JSValueRef value) = 0; + + virtual JSRunTimeValue GetObjectPrototype(JSRunTimeObject referenceValue) = 0; + + virtual JSRunTimeObject toObjectFromValue(JSRunTimeValue js_value) = 0; + }; + +} // namespace unicorn + +#endif // FLUTTER_UNICORN_RUNTIME_ENGINE_CONTEXT_H_ diff --git a/weex_core/Source/js_runtime/runtime/js_runtime_conversion.cpp b/weex_core/Source/js_runtime/runtime/js_runtime_conversion.cpp new file mode 100644 index 0000000000..ab2c77109a --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/js_runtime_conversion.cpp @@ -0,0 +1,23 @@ +/** + * 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 陈佩翰 on 2019/1/28. +// + +#include "js_runtime_conversion.h" diff --git a/weex_core/Source/js_runtime/runtime/js_runtime_conversion.h b/weex_core/Source/js_runtime/runtime/js_runtime_conversion.h new file mode 100644 index 0000000000..f73e128d12 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/js_runtime_conversion.h @@ -0,0 +1,42 @@ +/** + * 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 陈佩翰 on 2019/1/28. +// + +#ifndef FLUTTER_UNICORN__JS_RUNTIME_CONVERSION_H +#define FLUTTER_UNICORN__JS_RUNTIME_CONVERSION_H + +#include "base.h" +#include "runtime_values.h" + +namespace unicorn { + class JSRuntimeConversion { + public: + static JSRunTimeValue RuntimeValueToJSRuntimeValue(EngineContext* ctx, + JSRunTimeClass class_ref, + const RuntimeValues* value); + + static ScopeValues JSRunTimeValueToRuntimeValue(EngineContext* ctx, + JSRunTimeObject thiz, + JSRunTimeValue value); + }; + +} +#endif //FLUTTER_UNICORN__JS_RUNTIME_CONVERSION_H diff --git a/weex_core/Source/js_runtime/runtime/jsc/binding_macro_jsc.h b/weex_core/Source/js_runtime/runtime/jsc/binding_macro_jsc.h new file mode 100644 index 0000000000..34f6f2204a --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/jsc/binding_macro_jsc.h @@ -0,0 +1,420 @@ +/** + * 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 FLUTTER_UNICORN_RUNTIME_JSC_BINDING_MACRO_JSC_H_ +#define FLUTTER_UNICORN_RUNTIME_JSC_BINDING_MACRO_JSC_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "js_runtime/runtime/base.h" +#include "js_runtime/runtime/engine_context.h" +#include "js_runtime/runtime/jsc/jsc_utils.h" +#include "js_runtime/runtime/runtime_object.h" +#include "js_runtime/runtime/runtime_vm.h" +#include "js_runtime/utils/log_utils.h" + +#include "JavaScriptCore/JSObjectRef.h" + +typedef JSObjectGetPropertyCallback GetterCallback; +typedef JSObjectSetPropertyCallback SetterCallback; +typedef JSObjectCallAsFunctionCallback FunctionCallback; + +__attribute__((unused)) +static JSValueRef MakeClassToFunctionType( + JSContextRef ctx, + JSObjectRef function, + JSObjectRef thiz, size_t argc, + const JSValueRef *argv, + JSValueRef *exception +) { + auto ret = unicorn::RuntimeValues::MakeUndefined(); + JSValueRef prop = + unicorn::Conversion::RuntimeValueToJSValue(ctx, nullptr, ret.get()); + return prop; +} + +class SetterAndGetterCallback { +public: + SetterAndGetterCallback() : getter_(nullptr), setter_(nullptr) {} + + ~SetterAndGetterCallback() = default; + + GetterCallback getter_; + SetterCallback setter_; +}; + +// define class member get and set callback +#define GET_CALLBACK_FUNCTION(member_name_) Get ## member_name_ ## Callback +#define SET_CALLBACK_FUNCTION(member_name_) Set ## member_name_ ## Callback + +// define class member function callback +#define METHOD_CALLBACK_FUNCTION(method_name_) method_name_##Callback + +// define class static member function callback +#define STATIC_METHOD_CALLBACK_FUNCTION(method_name_) method_name_##Callback + +// define class constructor callback +#define CONSTRUCTOR_CALLBACK_FUNCTION(class_) class_##ConstructorCallback + +// define class object finalize callback +#define FINALIZE_CALLBACK_FUNCTION(class_) class_##FinalizeCallback + +// define global class JSClassRef, we need to create class object +// define js class for class +#define DECLARE_CLASS_REGISTER_OP(class_) \ +static JSClassRef s_jsclass_##class_; \ +static JSClassRef CreateClassRef(unicorn::EngineContext* context); +static bool s_is_global_binding = false; + +#define SET_IS_GLOBAL \ +s_is_global_binding = true; + +#define CHECK_IS_BASIC_TYPE(type_name_) \ + bool is_basic_type = false; \ + if (std::is_integral::type>::value) \ + is_basic_type = true; \ + if (std::is_floating_point< \ + std::remove_reference::type>::value) \ + is_basic_type = true; \ + if (std::is_same::type>::value) \ + is_basic_type = true; \ + if (std::is_same::type>::value)\ + is_basic_type = true; \ + if (std::is_same::type>::value) \ + is_basic_type = true; + +#define MEMBER_GET_CALLBACK_FUNCTION(class_, member_name_) \ +static JSValueRef GET_CALLBACK_FUNCTION(member_name_)( \ + JSContextRef ctx, \ + JSObjectRef thiz, \ + JSStringRef propertyName, \ + JSValueRef* exception \ + ) { \ + class_* obj = static_cast(JSObjectGetPrivate(thiz)); \ + const auto ret = obj->member_name_(); \ + std::string name = #member_name_; \ + JSValueRef prop = \ + unicorn::Conversion::RuntimeValueToJSValue(ctx, nullptr, ret.get()); \ + return prop; \ +} + +#define MEMBER_SET_CALLBACK_FUNCTION(class_, member_name_) \ +static bool SET_CALLBACK_FUNCTION(member_name_)( \ + JSContextRef ctx, \ + JSObjectRef thiz, \ + JSStringRef propertyName, \ + JSValueRef value, \ + JSValueRef* exception \ + ) { \ + class_* obj = static_cast(JSObjectGetPrivate(thiz)); \ + auto val = unicorn::Conversion::JSValueToRuntimeValue(ctx, thiz, value); \ + obj->member_name_(std::move(val)); \ + return true; \ +} + +#define CLASS_MEMBER_SET_CALLBACK(class_, member_name_) \ +MEMBER_SET_CALLBACK_FUNCTION(class_, member_name_) \ + +#define CLASS_MEMBER_GET_CALLBACK(class_, member_name_) \ +MEMBER_GET_CALLBACK_FUNCTION(class_, member_name_) + + +/* This macro for the binding function without return type */ +#define CLASS_VOID_METHOD_CALLBACK(class_, method_name_) \ +static JSValueRef METHOD_CALLBACK_FUNCTION(method_name_)( \ + JSContextRef ctx, \ + JSObjectRef function, \ + JSObjectRef thiz, size_t argc, \ + const JSValueRef* argv, \ + JSValueRef *exception \ + ) { \ + class_* obj = static_cast(JSObjectGetPrivate(thiz)); \ + std::vector arguments; \ + unicorn::Conversion::JSValuesArrayToRuntimeValues(ctx, thiz, argc, \ + argv, \ + arguments); \ + auto ret = obj->method_name_(arguments); \ + return unicorn::Conversion::RuntimeValueToJSValue(ctx, \ + nullptr, ret.get()); \ +} + +/* This macro for the binding function with return type */ +#define CLASS_METHOD_CALLBACK(class_, method_name_) \ +static JSValueRef METHOD_CALLBACK_FUNCTION(method_name_)( \ + JSContextRef ctx, \ + JSObjectRef function, \ + JSObjectRef thiz, size_t argc, \ + const JSValueRef* argv, \ + JSValueRef *exception \ + ) { \ + \ + auto addr = JSObjectGetPrivate(thiz); \ + if(nullptr == addr && s_is_global_binding){ \ + JSObjectRef globalObject = JSContextGetGlobalObject(ctx); \ + addr = JSObjectGetPrivate(globalObject); \ + LOG_JS_RUNTIME("[Context]try get object %p at globalObject :%p, ",addr,thiz); \ + } \ + if( nullptr == addr){ \ + LOGE("[Context]return undefined!! can't get object %p at thiz:%p, method:%s",addr,thiz,#method_name_); \ + return JSValueMakeUndefined(ctx); \ + } \ + class_* obj = static_cast(addr); \ + std::vector arguments; \ + unicorn::Conversion::JSValuesArrayToRuntimeValues(ctx, thiz, argc, \ + argv, \ + arguments); \ + auto ret = obj->method_name_(arguments); \ + JSValueRef prop = \ + unicorn::Conversion::RuntimeValueToJSValue(ctx, nullptr, ret.get()); \ + return prop; \ +} + +#define CLASS_STATIC_METHOD_CALLBACK(class_name_, member_name_) \ +static JSValueRef STATIC_METHOD_CALLBACK_FUNCTION(member_name_)( \ + JSContextRef ctx, JSObjectRef function, \ + JSObjectRef thiz, \ + size_t argc, const JSValueRef argv[], \ + JSValueRef* exception) { \ + std::vector arguments; \ + unicorn::Conversion::JSValuesArrayToRuntimeValues(ctx, thiz, argc, \ + argv, arguments); \ + JSGlobalContextRef global = JSContextGetGlobalContext(ctx); \ + EngineContext* context = RuntimeVM::GetEngineContext( \ + static_cast(global));\ + auto thiz_object = new RuntimeObject(context); \ + thiz_object->SetJSObject(thiz); \ + auto thiz_value = RuntimeValues::MakeCommonObject( \ + static_cast(thiz_object), \ + nullptr); \ + auto ret = class_name_::member_name_(std::move(thiz_value), arguments); \ + return unicorn::Conversion::RuntimeValueToJSValue(ctx, \ + nullptr, ret.get()); \ +} + +#define CLASS_CONSTRUCTOR_CALLBACK(class_) \ +static JSObjectRef CONSTRUCTOR_CALLBACK_FUNCTION(class_)( \ + JSContextRef ctx, \ + JSObjectRef constructor, \ + size_t argc, \ + const JSValueRef argv[], \ + JSValueRef* exception \ + ) { \ + std::vector arguments; \ + unicorn::Conversion::JSValuesArrayToRuntimeValues(ctx, nullptr, argc, \ + argv, \ + arguments); \ + JSGlobalContextRef global = JSContextGetGlobalContext(ctx); \ + unicorn::EngineContext* context = unicorn::RuntimeVM::GetEngineContext( \ + static_cast(global));\ + auto thiz_object = new unicorn::RuntimeObject(context); \ + thiz_object->SetJSObject(constructor); \ + auto thiz_value = unicorn::RuntimeValues::MakeCommonObject( \ + static_cast(thiz_object), \ + nullptr); \ + class_* t = class_::JSCreate(context,std::move(thiz_value), arguments); \ + JSObjectRef ob = JSObjectMake(ctx, class_::s_jsclass_##class_, \ + static_cast(t)); \ + return ob; \ +} + +#define CLASS_FINALIZE_CALLBACK(class_) \ +static void FINALIZE_CALLBACK_FUNCTION(class_)(JSObjectRef object) { \ + class_* t = static_cast(JSObjectGetPrivate(object)); \ + class_::JSFinalize(t); \ +} + +#define CLASS_REGISTER_START(class_name_, js_class_name_) \ +JSClassRef class_name_::s_jsclass_##class_name_ = nullptr; \ +JSClassRef class_name_::CreateClassRef(unicorn::EngineContext* context) { \ + JSContextRef ctx = nullptr != context \ + ?static_cast(context->GetContext()) \ + :nullptr; \ + std::vector class_values; \ + std::vector class_functions; \ + JSClassDefinition class_definition = kJSClassDefinitionEmpty; \ + std::string js_name = #js_class_name_; \ + std::vector tmp; \ + std::unordered_map static_functions; \ + std::unordered_map static_members; \ + std::map members_map; \ + bool enable_constructor = false; \ + JSClassRef parent_ref = nullptr; + +#define REGISTER_PARENT_CLASS(parent_name_) \ + parent_ref = parent_name_::s_jsclass_##parent_name_; + +#define CLASS_CONSTRUCTOR_ENABLE(class_name_) \ + enable_constructor = true; \ + if (enable_constructor) { \ + class_definition.finalize = FINALIZE_CALLBACK_FUNCTION(class_name_); \ + class_definition.callAsConstructor = \ + CONSTRUCTOR_CALLBACK_FUNCTION(class_name_); \ + class_definition.callAsFunction = MakeClassToFunctionType; \ + } + +#define REGISTER_GET_CALLBACK(class_name_, member_name_) \ + { \ + std::string name = #member_name_; \ + auto& temp = members_map[name]; \ + temp.getter_ = GET_CALLBACK_FUNCTION(member_name_); \ + } + +#define REGISTER_SET_CALLBACK(class_name_, member_name_) \ + { \ + std::string name = #member_name_; \ + auto& temp = members_map[name]; \ + temp.setter_ = SET_CALLBACK_FUNCTION(member_name_); \ + } + +/** +* magic bug : + * class_functions.push_back(...) with first params + * use name.c_str() ,the vector result order is confusion + * example register method named :log、addEventListener、addEventListenerTest、test + * for-each vector,the result item named (log,addEventListenerTest,addEventListenerTest,test) + * but use #method_name_ ,it works fine + * so why ?????????????????????????????? +*/ + +#define REGISTER_METHOD_CALLBACK(class_name_, method_name_) \ + { \ + std::string name = #method_name_; \ + tmp.push_back(name); \ + class_functions.push_back({ \ + #method_name_, \ + METHOD_CALLBACK_FUNCTION(method_name_), \ + kJSPropertyAttributeNone \ + }); \ + } + +#define REGISTER_STATIC_METHOD_CALLBACK(class_name_, method_name_) \ + { \ + std::string name = #method_name_; \ + JSStringRef f_name = JSStringCreateWithUTF8CString(name.c_str()); \ + JSObjectRef object = JSObjectMakeFunctionWithCallback(ctx, f_name, \ + STATIC_METHOD_CALLBACK_FUNCTION(method_name_));\ + static_functions[f_name] = object; \ + } + +#define REGISTER_STATIC_MEMBER(class_name_, member_name_, type_name_) \ + { \ + std::string name = #member_name_; \ + JSStringRef m_name = JSStringCreateWithUTF8CString(name.c_str()); \ + type_name_* ptr = &class_name_::member_name_; \ + auto scope = ToRuntimeValues( \ + static_cast(ptr), name); \ + JSValueRef ref = \ + unicorn::Conversion::RuntimeValueToJSValue(ctx, \ + nullptr, scope.get());\ + static_members[m_name] = ref; \ + } + +#define CLASS_REGISTER_END(class_name_) \ + for (auto& h : members_map) { \ + class_values.push_back({ \ + h.first.c_str(), \ + h.second.getter_, \ + h.second.setter_, \ + kJSPropertyAttributeNone \ + }); \ + } \ + class_values.push_back({0, 0, 0, 0}); \ + class_functions.push_back({0, 0, 0}); \ + class_definition.version = 0; \ + class_definition.attributes = 0; \ + class_definition.className = js_name.c_str(); \ + class_definition.parentClass = parent_ref; \ + class_definition.staticValues = &class_values.front(); \ + class_definition.staticFunctions = &class_functions.front(); \ + class_definition.initialize = 0; \ + JSClassRef clazz = JSClassCreate(&class_definition); \ + class_name_::s_jsclass_##class_name_ = clazz; \ + if (enable_constructor) { \ + JSStringRef str = JSStringCreateWithUTF8CString( \ + class_definition.className); \ + JSObjectRef constructor = JSObjectMake(ctx, clazz, nullptr); \ + JSObjectRef proto_type = JSObjectMakeConstructor(ctx, clazz, \ + class_definition.callAsConstructor); \ + for (auto& m : static_members) { \ + JSObjectSetProperty(ctx, proto_type, m.first, \ + m.second, 0, nullptr); \ + JSStringRelease(m.first); \ + } \ + for (auto& f : static_functions) { \ + JSObjectSetProperty(ctx, proto_type, f.first, \ + f.second, 0, nullptr); \ + JSStringRelease(f.first); \ + } \ + /* this way to make binding class to be function type right or not */ \ + JSObjectSetPrototype(ctx, constructor, proto_type); \ + JSObjectRef global = JSContextGetGlobalObject(ctx); \ + JSObjectSetProperty(ctx, global, str, constructor, \ + kJSPropertyAttributeNone, NULL); \ + JSStringRelease(str); \ + } \ + return clazz; \ +} + +#define CLASS_OBJECT_REGISTER(class_name_) \ +static void* Register##class_name_##ToJSObject(EngineContext* context, \ + const char* object_name, \ + void* data) { \ + if (context == nullptr || data == nullptr || \ + g_##class_name_##Ref == nullptr) \ + return nullptr; \ + JSContextRef ctx = static_cast(context->GetContext()); \ + JSObjectRef global_object = JSContextGetGlobalObject(ctx); \ + JSObjectRef js_object = JSObjectMake(ctx, \ + class_name_::s_jsclass_##class_name_, \ + data); \ + JSStringRef js_name = JSStringCreateWithUTF8CString(object_name); \ + JSObjectSetProperty(ctx, global_object, js_name, js_object, \ + kJSPropertyAttributeNone, NULL); \ + JSStringRelease(js_name); \ + return static_cast(js_object); \ +} + +#define GLOBAL_METHOD_REGISTER(method_name_) \ +{ \ + std::string name = #method_name_; \ + JSObjectRef global = JSContextGetGlobalObject(ctx); \ + JSStringRef function_name = \ + JSStringCreateWithUTF8CString(name.c_str()); \ + JSObjectRef function_object = JSObjectMakeFunctionWithCallback(ctx, \ + function_name, \ + &method_name_); \ + JSObjectSetProperty(ctx, \ + global, \ + function_name, \ + function_object, \ + kJSPropertyAttributeNone, \ + nullptr); \ + JSStringRelease(function_name); \ +} + +#endif // FLUTTER_UNICORN_RUNTIME_JSC_BINDING_MACRO_JSC_H_ diff --git a/weex_core/Source/js_runtime/runtime/jsc/engine_context_jsc.cc b/weex_core/Source/js_runtime/runtime/jsc/engine_context_jsc.cc new file mode 100644 index 0000000000..f4f3bdc993 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/jsc/engine_context_jsc.cc @@ -0,0 +1,338 @@ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#include "js_runtime/runtime/jsc/engine_context_jsc.h" + +#include +#include +#include "js_runtime/runtime/jsc/jsc_utils.h" +#include "js_runtime/runtime/jsc/binding_macro_jsc.h" +#include "js_runtime/runtime/runtime_values.h" +#include "js_runtime/runtime/runtime_vm.h" +#include "js_runtime/utils/log_utils.h" + +namespace unicorn { + + EngineContextJSC::EngineContextJSC(EngineContextDelegate *delegate, + RuntimeVM *vm, JSClassRef globalObjectClassRef) + : delegate_(delegate), vm_(vm) { + InitializeContext(globalObjectClassRef); + } + + EngineContextJSC::~EngineContextJSC() { + JSGlobalContextRelease(context_); + + if (delegate_) delegate_->OnEngineContextFinalized(); + delegate_ = nullptr; + + LOGE("[release] release ctx :%p", context_); + } + + void EngineContextJSC::InitializeContext(JSClassRef globalClassRef) { + JSContextGroupRef context_group = + static_cast(vm_->EngineVM()); + context_ = JSGlobalContextCreateInGroup(context_group, globalClassRef); + LOG_JS_RUNTIME("[Context] EngineContextJSC::create context :%p ,globalObject :%p", context_, + JSContextGetGlobalObject(context_)); + + if (delegate_) delegate_->OnEngineContextInitialized(); + } + + bool EngineContextJSC::RunJavaScript(const std::string &script, std::string *runException) { + LOG_JS_RUNTIME("EngineContextJSC:: RunJavaScript onContext :%p, script :%s", context_, script.c_str()); + + JSStringRef source = JSStringCreateWithUTF8CString(script.c_str()); + + + JSValueRef exceptionRef = nullptr; + JSEvaluateScript(context_, source, NULL, NULL, 0, &exceptionRef); + JSStringRelease(source); + if (exceptionRef && nullptr != runException) { + Conversion::JSValueToStdString(context_,exceptionRef,runException); + return false; + } + LOG_JS_RUNTIME("WeexRuntime:: RunJavaScript succeed this"); + return true; + } + + ScopeValues EngineContextJSC::RunJavaScriptWithResult(const std::string &script, std::string *exception) { + LOG_JS_RUNTIME("EngineContextJSC:: RunJavaScriptWithResult : %s", script.c_str()); + JSStringRef source = JSStringCreateWithUTF8CString(script.c_str()); + JSValueRef exceptionRef = nullptr; + + + + JSValueRef result = JSEvaluateScript(context_, source, NULL, NULL, 0, &exceptionRef); + if (!exceptionRef) { + Conversion::JSValueToStdString(context_, exceptionRef, exception); + } + + JSStringRelease(source); + return Conversion::JSValueToRuntimeValue(context_, nullptr, result); + } + + + void EngineContextJSC::ThrowJSError(const std::string &error) {} + + void EngineContextJSC::ThrowException(const std::string &error) {} + + void EngineContextJSC::SetGlobalPropertyValue(const std::string &property_id, + ScopeValues value) { + JSObjectRef global = JSContextGetGlobalObject(context_); + JSValueRef exc = nullptr; + JSStringRef str_ref = JSStringCreateWithUTF8CString(property_id.c_str()); + JSObjectSetProperty( + context_, + global, + str_ref, + Conversion::RuntimeValueToJSValue(context_, nullptr, value.get()), + kJSPropertyAttributeNone, + &exc); + JSStringRelease(str_ref); + } + + ScopeValues EngineContextJSC::GetGlobalProperty(std::string property_id) { + JSObjectRef global = JSContextGetGlobalObject(context_); + JSValueRef exc = nullptr; + JSStringRef str = JSStringCreateWithUTF8CString(property_id.c_str()); + JSValueRef result = JSObjectGetProperty(context_, global, str, &exc); + if (exc) { + } + + JSStringRelease(str); + return Conversion::JSValueToRuntimeValue(context_, global, result); + } + + EngineContext *EngineContext::CreateEngineContext( + EngineContextDelegate *delegate, RuntimeVM *vm, JSClassRef globalObjectClass) { + return new EngineContextJSC(delegate, vm, globalObjectClass); + } + + JSValueRef + EngineContextJSC::callJavaScriptFunc(RuntimeObject *target, const std::string &name, std::vector &args, + std::string *exception) { + const char *cName = name.c_str(); + JSStringRef funcNameStr = JSStringCreateWithUTF8CString(cName); + JSValueRef result = nullptr; + JSValueRef exc = nullptr; + JSObjectRef targetObjectRef = nullptr; + if (nullptr == target) { + LOG_JS_RUNTIME("EngineContextJSC callJavaScriptFunc targetObjectRef GlobalObject :%s", cName); + targetObjectRef = JSContextGetGlobalObject(context_); + } else { + // LOG_TEST("EngineContextJSC callJavaScriptFunc target->GetJSObject() :%s", cName); + targetObjectRef = target->GetJSObject(); + } + + JSValueRef funcValueRef = JSObjectGetProperty(context_, targetObjectRef, funcNameStr, &exc); + + if(funcNameStr) { + JSStringRelease(funcNameStr); + } + if (exc || JSValueIsUndefined(context_, funcValueRef)) { + LOG_JS_RUNTIME("EngineContext can't find func Name :%s !!!!!!", cName); + return nullptr; + } + + JSObjectRef funcObjectRef = JSValueToObject(context_, funcValueRef, &exc); + + if (exc && JSValueIsString(context_, exc)) { + Conversion::JSValueToStdString(context_, exc, exception); + } + + if (exc || !funcObjectRef || !JSObjectIsFunction(context_, funcObjectRef)) { + return nullptr; + } + + // LOG_TEST("EngineContextJSC deal func %s args, agrSize :%d", cName, args.size()); + JSValueRef argv_js[args.size()]; + for (size_t i = 0; i < args.size(); i++) { + argv_js[i] = Conversion::RuntimeValueToJSValue(context_, nullptr, args[i].get()); + } + + // LOG_TEST("EngineContextJSC try call func :%s", cName); + result = JSObjectCallAsFunction(context_, funcObjectRef, targetObjectRef, args.size(), argv_js, &exc); + + if (!result || exc) { + Conversion::JSValueToStdString(context_, exc, exception); + return nullptr; + } + LOG_JS_RUNTIME("EngineContextJSC call func :%s succeed ~~~ ,return result :%d", cName, result); + return result; + } + + JSValueRef EngineContextJSC::GetPropertyValueFromObject(std::string property_id, JSRunTimeObject object) { + if (nullptr == object) { + LOG_JS_RUNTIME("EngineContextJSC GetPropertyValueFromObject check object failed from id:%s", + property_id.c_str()); + return nullptr; + } + // LOG_TEST("EngineContextJSC try GetPropertyValueFromObject :%s", property_id.c_str()); + JSStringRef str = JSStringCreateWithUTF8CString(property_id.c_str()); + JSValueRef exc = nullptr; + JSValueRef resultValue = JSObjectGetProperty(context_, object, str, &exc); +// if (exc) { +// Conversion::printJSValueRefException(context_, exc); +// } + JSStringRelease(str); + if (resultValue && !JSValueIsUndefined(context_, resultValue)) { + // LOG_TEST("EngineContextJSC GetPropertyValueFromObject succeed :%s", property_id.c_str()); + return resultValue; + } + return nullptr; + } + + bool EngineContextJSC::SetObjectPrototypeFromValue(JSObjectRef target, JSValueRef referenceValue) { + LOG_JS_RUNTIME("EngineContextJSC SetObjectPrototypeFromValue "); + if (nullptr == target && referenceValue == nullptr) { + return false; + } + if (nullptr == referenceValue) { + referenceValue = JSObjectGetPrototype(context_, JSContextGetGlobalObject(context_)); + // referenceValue = JSContextr + } + JSObjectSetPrototype(context_, target, referenceValue); + return true; + } + + JSObjectRef EngineContextJSC::toObjectFromValue(JSValueRef js_value) { + if (nullptr == js_value) { + LOG_JS_RUNTIME("EngineContextJSC toObjectFromValue check failed !"); + return nullptr; + } + JSValueRef exc = nullptr; + JSObjectRef convertObjectRef = JSValueToObject(context_, js_value, &exc); + //Conversion::printJSValueRefException(context_, exc); + if (convertObjectRef) { + return convertObjectRef; + } + return nullptr; + } + + JSValueRef EngineContextJSC::GetObjectPrototype(JSObjectRef object) { + JSValueRef type = nullptr; + if (nullptr == object) { + // LOG_TEST("EngineContextJSC get global objectPrototype "); + type = JSObjectGetPrototype(context_, JSContextGetGlobalObject(context_)); + } else { + // LOG_TEST("EngineContextJSC get target objectPrototype "); + type = JSObjectGetPrototype(context_, object); + } + return type; + } + + bool EngineContextJSC::GetObjectPropertyNameArray(JSRunTimeObject object, std::vector &nameArrays) { + + if (nullptr == object) { + LOG_JS_RUNTIME("[EngineContextJSC] GetObjectPropertyNameArray use globalObject "); + object = JSContextGetGlobalObject(context_); + } + + auto pArray = JSObjectCopyPropertyNames(context_, object); + size_t keyCount = JSPropertyNameArrayGetCount(pArray); + for (size_t i = 0; i < keyCount; ++i) { + auto propertyName_ = JSPropertyNameArrayGetNameAtIndex(pArray, i); + if (propertyName_ == nullptr) { + LOG_JS_RUNTIME("[EngineContextJSC] create instance propertyName_ == null"); + return false; + } +// auto propertyValue_ = JSObjectGetProperty(context_, object, propertyName_, NULL); +// if(propertyValue_ == nullptr) { +// LOG_TEST("dyy create instance propertyValue_ == null"); +// continue; +// } + std::string result; + size_t max_bytes = JSStringGetMaximumUTF8CStringSize(propertyName_); + result.resize(max_bytes); + size_t bytes_written = JSStringGetUTF8CString(propertyName_, &result[0], max_bytes); + if (max_bytes == 0) { + return false; + } + result.resize(bytes_written - 1); + + LOG_JS_RUNTIME("[EngineContextJSC] GetObjectPropertyName item :%s", result.c_str()); + + //JSStringRelease(propertyName_); + nameArrays.push_back(result); + } + JSPropertyNameArrayRelease(pArray); + return true; + } + + bool EngineContextJSC::setObjectValue(JSRunTimeObject targetObject, const std::string &key, JSRunTimeValue value) { + LOG_JS_RUNTIME("EngineContextJSC enter func setObjectValue onContext %p, [%s,%d],val:%p", + context_, + key.c_str(), + JSValueGetType(context_, value), + value + ); + if (nullptr == targetObject) { + //LOG_TEST("EngineContextJSC setObjectValue to global "); + targetObject = JSContextGetGlobalObject(context_); + } + + auto str = JSStringCreateWithUTF8CString(key.c_str()); + JSValueRef exe = NULL; + // LOG_TEST("try EngineContextJSC setObjectValue :%s", key.c_str()); + JSObjectSetProperty(context_, targetObject, str, value, 0, &exe); + //LOG_TEST("EngineContextJSC setObjectValue succeed "); + JSStringRelease(str); + if (exe) { + std::string jse; + Conversion::JSValueToStdString(context_, exe, &jse); + LOGE("[JSExcepion] ------> %s", jse.c_str()); + + return false; + } else { + return true; + } + } + + JSObjectRef EngineContextJSC::GetGlobalObjectInContext() { + return JSContextGetGlobalObject(context_); + } + + void EngineContextJSC::BindDataToObject(JSRunTimeObject targetObj, void *data) { + if (nullptr == targetObj) { + return; + } + JSObjectSetPrivate(targetObj, data); + } + + void EngineContextJSC::removeObjectBindData(JSRunTimeObject targetObj) { + if (nullptr == targetObj) { + return; + } + JSObjectSetPrivate(targetObj, nullptr); + } + + void EngineContextJSC::SetName(const std::string &name) { + this->context_name = name; + } + + std::string EngineContextJSC::GetName() { + return this->context_name; + } + + ScopeValues EngineContextJSC::CallJavaScriptFuncWithRuntimeValue(RuntimeObject *target, const std::string &name, + std::vector &args, + std::string *exception) { + JSValueRef jsValue = this->callJavaScriptFunc(target,name,args,exception); + return Conversion::JSValueToRuntimeValue(context_, nullptr, jsValue); + } + +} +// namespace unicorn diff --git a/weex_core/Source/js_runtime/runtime/jsc/engine_context_jsc.h b/weex_core/Source/js_runtime/runtime/jsc/engine_context_jsc.h new file mode 100644 index 0000000000..2d71aa4812 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/jsc/engine_context_jsc.h @@ -0,0 +1,115 @@ +/** + * 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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_JSC_ENGINE_CONTEXT_JSC_H_ +#define FLUTTER_UNICORN_RUNTIME_JSC_ENGINE_CONTEXT_JSC_H_ + +#include "JavaScriptCore/JavaScript.h" +#include +#include +#include "js_runtime/runtime/engine_context.h" +#include "js_runtime/runtime/runtime_values.h" + +namespace unicorn { + + class RuntimeVM; + + class EngineContextJSC : public EngineContext { + public: + EngineContextJSC(EngineContextDelegate *delegate, RuntimeVM *vm, JSClassRef globalObjectClass); + + virtual ~EngineContextJSC(); + + void InitializeContext(JSClassRef globalObjectClass) override; + + bool RunJavaScript(const std::string &script, std::string *exception) override; + + ScopeValues RunJavaScriptWithResult(const std::string &script, std::string *exception) override; + + JSValueRef callJavaScriptFunc(RuntimeObject *target, const std::string &name, std::vector &args, + std::string *exception) override; + + + void ThrowJSError(const std::string &error) override; + + void ThrowException(const std::string &error) override; + + void *GetContext() const override { return static_cast(context_); } + + void SetGlobalPropertyValue(const std::string &property_id, + ScopeValues value) override; + + JSObjectRef GetGlobalObjectInContext() override; + + void BindDataToObject(JSObjectRef targetObj, void *data) override; + + void removeObjectBindData(JSObjectRef targetObj) override; + + ScopeValues GetGlobalProperty(std::string property_id) override; + + JSValueRef GetPropertyValueFromObject(std::string property_id, JSObjectRef object) override; + + + bool SetObjectPrototypeFromValue(JSObjectRef target, JSValueRef referenceValue) override; + + JSValueRef GetObjectPrototype(JSObjectRef referenceObject) override; + + JSObjectRef toObjectFromValue(JSValueRef js_value) override; + + + bool GetObjectPropertyNameArray(JSRunTimeObject object, std::vector &nameArrays) override; + + bool setObjectValue(JSRunTimeObject targetObject, const std::string &key, JSRunTimeValue value) override; + + void SetName(const std::string &name) override; + + std::string GetName() override; + + ScopeValues + CallJavaScriptFuncWithRuntimeValue(RuntimeObject *target, const std::string &name, std::vector &args, + std::string *exception)override ; + + + private: + EngineContextDelegate *delegate_; + RuntimeVM *vm_; + + JSGlobalContextRef context_; + + std::string context_name; + }; + +} // namespace unicorn + +#endif // FLUTTER_UNICORN_RUNTIME_JSC_ENGINE_CONTEXT_JSC_H_ diff --git a/weex_core/Source/js_runtime/runtime/jsc/jsc_base.h b/weex_core/Source/js_runtime/runtime/jsc/jsc_base.h new file mode 100644 index 0000000000..01ba13b8ad --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/jsc/jsc_base.h @@ -0,0 +1,48 @@ +/** + * 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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_JSC_JSC_BASE_H_ +#define FLUTTER_UNICORN_RUNTIME_JSC_JSC_BASE_H_ + +#include +typedef JSContextRef JSRunTimeContext; +typedef JSClassRef JSRunTimeClass; +typedef JSObjectRef JSRunTimeObject; +typedef JSValueRef JSRunTimeValue; +typedef JSObjectGetPropertyCallback GetterCallback; +typedef JSObjectSetPropertyCallback SetterCallback; +typedef JSObjectCallAsFunctionCallback FunctionCallback; +typedef JSObjectCallAsConstructorCallback ConstructorCallback; + +#endif // FLUTTER_UNICORN_RUNTIME_JSC_JSC_BASE_H_ diff --git a/weex_core/Source/js_runtime/runtime/jsc/jsc_utils.cc b/weex_core/Source/js_runtime/runtime/jsc/jsc_utils.cc new file mode 100644 index 0000000000..cd6928a649 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/jsc/jsc_utils.cc @@ -0,0 +1,451 @@ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#include "js_runtime/runtime/jsc/jsc_utils.h" + +#include +#include +#include "JavaScriptCore/JSBase.h" +#include "JavaScriptCore/JSStringRef.h" +#include "JavaScriptCore/JSValueRef.h" + +#include "js_runtime/runtime/jsc/runtime_values_jsc.h" +#include "js_runtime/runtime/runtime_object.h" +#include "js_runtime/runtime/runtime_values.h" +#include "js_runtime/utils/log_utils.h" +#include "js_runtime/runtime/js_runtime_conversion.h" + +namespace unicorn { + + static JSClassRef kDefaultClass = nullptr; + + JSValueRef JSRuntimeConversion::RuntimeValueToJSRuntimeValue(EngineContext *ctx, + JSClassRef class_ref, + const RuntimeValues *value) { + return Conversion::RuntimeValueToJSValue(static_cast(ctx->GetContext()), class_ref, value); + } + + ScopeValues JSRuntimeConversion::JSRunTimeValueToRuntimeValue(EngineContext *ctx, + JSObjectRef thiz, + JSValueRef value) { + return Conversion::JSValueToRuntimeValue(static_cast(ctx->GetContext()), thiz, value); + } + + + JSValueRef Conversion::RuntimeValueToJSValue(JSContextRef ctx, + JSClassRef class_ref, + const RuntimeValues *value) { + if (value->IsUndefined()) { + // LOG_TEST("RuntimeValueToJSValue -> undefined"); + return JSValueMakeUndefined(ctx); + } else if (value->IsNull()) { + // LOG_TEST("RuntimeValueToJSValue -> null"); + return JSValueMakeNull(ctx); + } else if (value->IsBool()) { + bool b = false; + value->GetAsBoolean(&b); + /// LOG_TEST("[Context] RuntimeValueToJSValue -> value %p on ctx:%p, bool :%d", value, ctx, b); + return JSValueMakeBoolean(ctx, b); + } else if (value->IsInt()) { + int num = 0; + value->GetAsInteger(&num); + // LOG_TEST("RuntimeValueToJSValue -> int :%d", num); + return JSValueMakeNumber(ctx, static_cast(num)); + } else if (value->IsDouble()) { + double num = 0.0; + value->GetAsDouble(&num); + // LOG_TEST("RuntimeValueToJSValue -> double:%d", num); + return JSValueMakeNumber(ctx, num); + } else if (value->IsString()) { + std::string tmp; + value->GetAsString(&tmp); + // LOG_TEST("RuntimeValueToJSValue -> string:%s", tmp.c_str()); + JSStringRef str = JSStringCreateWithUTF8CString(tmp.c_str()); + auto result = JSValueMakeString(ctx, str); + JSStringRelease(str); + return result; + } else if (value->IsJsonObject()) { + std::string json_str; + value->GetAsUtf8JsonStr(json_str); + return Conversion::ParserUtf8CharJsonToJValueJSContextRef(ctx, json_str.c_str()); + } else if (value->IsObject()) { + // LOG_TEST("RuntimeValueToJSValue -> obj"); + BaseObject *native_ob = value->GetAsObject(); + if (class_ref == nullptr) { + auto clz = native_ob->GetRuntimeClass(); + if (clz) + class_ref = clz->GetJSClass(); + } + void *data = native_ob->GetDataPtr(); + if (data && !class_ref) { + // if class_ref == null, so the js object can not store data + // we use the default empty class instead + if (!kDefaultClass) { + JSClassDefinition class_definition = kJSClassDefinitionEmpty; + kDefaultClass = JSClassCreate(&class_definition); + } + class_ref = kDefaultClass; + } + JSObjectRef js_obj = JSObjectMake(ctx, class_ref, nullptr); + JSObjectSetPrivate(js_obj, data); + return js_obj; + } else if (value->IsMap()) { + // LOG_TEST("RuntimeValueToJSValue [start]-> map"); + const JSCMap *local = static_cast(value->GetAsMap()); + auto &map = local->GetMap(); + JSObjectRef thiz = local->GetThisObject(); + if (thiz == nullptr) { + thiz = JSObjectMake(ctx, nullptr, nullptr); + } + for (auto &iter : map) { + // LOG_TEST("RuntimeValueToJSValue [map key]-> %s", iter.first.c_str()); + JSStringRef str = JSStringCreateWithUTF8CString(iter.first.c_str()); + JSValueRef value_ref = RuntimeValueToJSValue(ctx, nullptr, iter.second); + JSObjectSetProperty(ctx, thiz, str, value_ref, 0, nullptr); + JSStringRelease(str); + } + // LOG_TEST("RuntimeValueToJSValue [end]-> map"); + return thiz; + } else if (value->IsFunction()) { + // LOG_TEST("RuntimeValueToJSValue -> func"); + const JSCFunction *local = + static_cast(value->GetAsFunction()); + return local->GetFunction(); + } +// JSValueIsArray is only used in ios 9.0 or above, so we just enable +// array in android now +//#if defined(OS_ANDROID) + else if (value->IsArray()) { + // LOG_TEST("RuntimeValueToJSValue[start] -> array"); + // const JSCArray *local = static_cast(value->GetAsArray()); +// JSObjectRef thiz = local->GetThisObject(); +// if (thiz == nullptr) { +// thiz = JSObjectMake(ctx, nullptr, nullptr); +// } + auto &array = value->GetAsArray()->GetArray(); + size_t length = array.size(); + // JSStringRef len_str = JSStringCreateWithUTF8CString("length"); +// JSObjectSetProperty(ctx, thiz, len_str, JSValueMakeNumber(ctx, length), +// 0, nullptr); +// JSStringRelease(len_str); + JSValueRef args[length]; + for (size_t i = 0; i < length; i++) { + args[i] = RuntimeValueToJSValue(ctx, nullptr, array[i]); + // JSObjectSetPropertyAtIndex(ctx, thiz, i, value_ref, nullptr); + } + JSValueRef js_exception = nullptr; + +// for (int i = 0; i < length; i++) { +// LOG_TEST("RuntimeValueToJSValue[item type: %d] ,onContext :%p", JSValueGetType(ctx, args[i]), ctx); +// } + + JSObjectRef js_array = JSObjectMakeArray(ctx, length, args, &js_exception); + printJSValueRefException(ctx, js_exception); + // LOG_TEST("RuntimeValueToJSValue[end] -> array"); + return js_array; + } +//#endif + + return JSValueMakeUndefined(ctx); + } + + + ScopeValues Conversion::JSValueToRuntimeValue(JSContextRef ctx, + JSObjectRef thiz, + JSValueRef value) { + std::vector stack_record; + std::string exception_str; + auto res = Conversion::JSValueToRuntimeValueWithCircleCheck(ctx,thiz,value,stack_record,exception_str); + if(!exception_str.empty()){ + LOGE("[JSValueToRuntimeValue] error :%s",exception_str.c_str()); + return unicorn::RuntimeValues::MakeNull(); + } else { + return res; + } + } + + ScopeValues Conversion::JSValueToRuntimeValueWithCircleCheck(JSContextRef ctx, JSObjectRef thiz, JSValueRef value, + std::vector &stack_record, + std::string &exception) { + if (!exception.empty()){ + return unicorn::RuntimeValues::MakeNull(); + } + if (JSValueIsNumber(ctx, value)) { + //LOGW("[JSValueToRuntimeValue] JSValueToRuntimeValue JSValueIsNumber "); + double origin = JSValueToNumber(ctx, value, nullptr); + if (origin == static_cast(origin)) { + return ScopeValues(new RuntimeValues(static_cast(origin))); + } + return ScopeValues(new RuntimeValues(origin)); + } else if (JSValueIsBoolean(ctx, value)) { + //LOGW("[JSValueToRuntimeValue] bool "); + return ScopeValues(new RuntimeValues(JSValueToBoolean(ctx, value))); + } else if (JSValueIsNull(ctx, value)) { + //LOGW("[JSValueToRuntimeValue] JSValueIsNull "); + return ScopeValues(new RuntimeValues(nullptr)); + } else if (JSValueIsUndefined(ctx, value)) { + //LOGW("[JSValueToRuntimeValue]JSValueIsUndefined "); + return ScopeValues(new RuntimeValues()); + } else if (JSValueIsString(ctx, value)) { + //LOGW("[JSValueToRuntimeValue] JSValueIsString enter"); + std::string result; + if (Conversion::JSValueToStdString(ctx, value, &result)) { + // LOGW("[JSValueToRuntimeValue] JSValueIsString result:%s", result.c_str()); + return RuntimeValues::MakeString(result); + } else { + // LOGW("[JSValueToRuntimeValue] JSValueIsString result: %s", "empty"); + return RuntimeValues::MakeString(std::string("")); + } + }// J + else if(JSValueIsObject(ctx,value)){ + for(int i=0;i(JSValueToNumber(ctx, + JSObjectGetProperty(ctx, ob, len_str, nullptr), nullptr)); + JSStringRelease(len_str); + auto holder = JSCArray::Create(ctx, ob); + for (int i = 0; i < length; i++) { + JSValueRef temp = JSObjectGetPropertyAtIndex(ctx, ob, i, nullptr); + //LOGW("[JSValueToRuntimeValue] before array index:%d ,valueType:%d,val_addr:%p", i, JSValueGetType(ctx, temp), temp); + auto native = JSValueToRuntimeValueWithCircleCheck(ctx, nullptr, temp,stack_record,exception); + if (!exception.empty()){ + exception.append(std::string(" on array index:")); + exception.append(std::to_string(i)); + stack_record.pop_back(); + return unicorn::RuntimeValues::MakeNull(); + } + // LOGW("[JSValueToRuntimeValue] after array index:%d ,valueType:%d", i, JSValueGetType(ctx, temp)); + holder->PushBack(native.release()); + } + stack_record.pop_back(); + auto array_holder = RuntimeValues::MakeArray(std::move(holder)); + return array_holder; + } else{ + std::vector properties; + JSUtils::GetPropertyNameArray(ctx, ob, properties); + //LOG_TEST("[Conversion] JSCMap::Create"); + auto jsc_map = JSCMap::Create(ctx, ob); + // LOG_TEST("[Conversion] JSValueToRuntimeValue else properties.size():%lu", properties.size()); + for (size_t i = 0; i < properties.size(); i++) { + // LOG_TEST("[Conversion] JSValueToRuntimeValue JSStringCreateWithUTF8CString name :%s",properties[i].c_str()); + JSStringRef str_ref = JSStringCreateWithUTF8CString( + properties[i].c_str()); + JSValueRef val = JSObjectGetProperty(ctx, ob, str_ref, nullptr); + JSStringRelease(str_ref); + // LOGW("[JSValueToRuntimeValue] map :key:%s,valueType:%d ,value_addr:%p,index:%d",properties[i].c_str(), JSValueGetType(ctx, val), val, i); + // LOG_TEST("[Conversion] Conversion::JSValueToRuntimeValue(ctx, ob, val)"); + auto native = Conversion::JSValueToRuntimeValueWithCircleCheck(ctx, ob, val,stack_record,exception); + if(!exception.empty()){ + exception.append(" on property:"); + exception.append(properties[i]); + stack_record.pop_back(); + return unicorn::RuntimeValues::MakeNull(); + } + jsc_map->Insert(properties[i], native.release()); + } + // LOG_TEST("[Conversion] map_holder = RuntimeValues::MakeMap(std::move(jsc_map)"); + stack_record.pop_back(); + auto map_holder = RuntimeValues::MakeMap(std::move(jsc_map)); + // LOG_TEST("[Conversion] return map_holder"); + return map_holder; + } + } + return ScopeValues(new RuntimeValues()); + } + + + void Conversion::JSValuesArrayToRuntimeValues(JSContextRef ctx, + JSObjectRef thiz, + size_t argc, const JSValueRef *argv, + std::vector &output) { + if (argc == 0 || argv == nullptr) + return; + for (size_t i = 0; i < argc; i++) { + output.push_back(JSValueToRuntimeValue(ctx, thiz, argv[i])); + } + } + + bool Conversion::JSValueToStdString(JSContextRef ctx, JSValueRef value, std::string *result) { + if (nullptr == value || JSValueIsNull(ctx, value)) { + return false; + } + JSStringRef str = JSValueToStringCopy(ctx, value, nullptr); + size_t max_bytes = JSStringGetMaximumUTF8CStringSize(str); + result->resize(max_bytes); + size_t bytes_written = JSStringGetUTF8CString(str, &(*result)[0], max_bytes); + if (max_bytes == 0) { + return false; + } + result->resize(bytes_written - 1); + // LOGE("Conversion::JSValueToStdString result: %s", result->c_str()); + + JSStringRelease(str); + return true; + } + + JSValueRef Conversion::ParserUtf8CharJsonToJValueJSContextRef(JSContextRef ctx, const char *utf_8_str) { + + + //LOG_TEST("Conversion::ParserUtf8CharJson : length:%d, str: %s", std::strlen(utf_8_str), utf_8_str); + JSStringRef jsonStrRef = JSStringCreateWithUTF8CString(utf_8_str); + JSValueRef jValue = JSValueMakeFromJSONString(ctx, jsonStrRef); + if (jsonStrRef) { + // LOG_TEST("Conversion::ParserUtf8CharJson : release str"); + JSStringRelease(jsonStrRef); + } + return jValue; + } + + void Conversion::printJSValueRefException(JSContextRef context, JSValueRef exc) { + if (nullptr == exc || JSValueIsNull(context, exc)) { + return; + } + std::string result; + JSStringRef str = JSValueToStringCopy(context, exc, nullptr); + size_t max_bytes = JSStringGetMaximumUTF8CStringSize(str); + result.resize(max_bytes); + size_t bytes_written = JSStringGetUTF8CString(str, &result[0], max_bytes); + if (max_bytes == 0) { + return; + } + result.resize(bytes_written - 1); + if (!result.empty()) { + LOG_JS_ERROR("[JS_ERROR] : %s", result.c_str()); + } + JSStringRelease(str); + } + + +///////////////////////////////////////////////////////////////////////////// +/*JSUtils implemention*/ + bool JSUtils::HasProperty(JSContextRef ctx, JSObjectRef ob, + const std::string &name) { + if (!ctx || !ob) + return false; + + JSContextRef context = static_cast(ctx); + JSObjectRef object = static_cast(ob); + JSStringRef str = JSStringCreateWithUTF8CString(name.c_str()); + bool ret = JSObjectHasProperty(context, object, str); + JSStringRelease(str); + return ret; + } + + void JSUtils::SetProperty(JSContextRef ctx, JSObjectRef ob, + JSClassRef clz, const std::string &name, + RuntimeValues *value) { + if (!ctx || !ob) + return; + + JSContextRef context = static_cast(ctx); + JSObjectRef object = static_cast(ob); + JSClassRef clasz = static_cast(clz); + JSStringRef str = JSStringCreateWithUTF8CString(name.c_str()); + JSValueRef ret = Conversion::RuntimeValueToJSValue(context, clasz, value); + JSObjectSetProperty(context, object, str, ret, 0, nullptr); + JSStringRelease(str); + } + + bool JSUtils::DeleteProperty(JSContextRef ctx, JSObjectRef ob, + const std::string &name) { + if (!ctx || !ob) + return false; + + JSContextRef context = static_cast(ctx); + JSObjectRef object = static_cast(ob); + JSStringRef str = JSStringCreateWithUTF8CString(name.c_str()); + bool ret = JSObjectDeleteProperty(context, object, str, nullptr); + JSStringRelease(str); + return ret; + } + + ScopeValues JSUtils::GetProperty(JSContextRef ctx, JSObjectRef ob, + const std::string &name) { + if (!ctx || !ob) + return ScopeValues(new RuntimeValues()); + + JSContextRef context = static_cast(ctx); + JSObjectRef object = static_cast(ob); + JSStringRef str = JSStringCreateWithUTF8CString(name.c_str()); + JSValueRef ret = JSObjectGetProperty(context, object, str, nullptr); + JSStringRelease(str); + return Conversion::JSValueToRuntimeValue(context, object, ret); + } + + void JSUtils::GetPropertyNameArray(JSContextRef ctx, JSObjectRef ob, + std::vector &native_array) { + if (!ctx || !ob) + return; + // LOG_TEST("[jsc_utils] GetPropertyNameArray "); + + JSContextRef context = static_cast(ctx); + JSObjectRef object = static_cast(ob); + JSPropertyNameArrayRef array_ref = JSObjectCopyPropertyNames(context, + object); + size_t count = JSPropertyNameArrayGetCount(array_ref); + + // LOG_TEST("[jsc_utils] JSPropertyNameArrayGetCount :%lu", count); + for (size_t i = 0; i < count; i++) { + JSStringRef str_ref = JSPropertyNameArrayGetNameAtIndex(array_ref, i); + size_t max_len = JSStringGetMaximumUTF8CStringSize(str_ref); + std::string holder; + holder.resize(max_len); + char *ptr = &holder[0]; + size_t bytes_written = JSStringGetUTF8CString(str_ref, ptr, max_len); + holder.resize(bytes_written - 1); + native_array.push_back(holder); + } + JSPropertyNameArrayRelease(array_ref); + } + + ScopeValues JSUtils::CallAsFunction(JSContextRef ctx, JSObjectRef thiz, + JSObjectRef function, + size_t argc, const JSValueRef argv[]) { + if (!ctx || !function) + return ScopeValues(new RuntimeValues()); + + JSContextRef context = static_cast(ctx); + JSObjectRef thiz_ob = static_cast(thiz); + JSObjectRef function_ob = static_cast(function); + JSValueRef ret = JSObjectCallAsFunction(context, function_ob, thiz_ob, + argc, argv, nullptr); + return Conversion::JSValueToRuntimeValue(context, thiz_ob, ret); + } +} // namespace unicorn diff --git a/weex_core/Source/js_runtime/runtime/jsc/jsc_utils.h b/weex_core/Source/js_runtime/runtime/jsc/jsc_utils.h new file mode 100644 index 0000000000..e3ec8b52bf --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/jsc/jsc_utils.h @@ -0,0 +1,98 @@ +/** + * 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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_JSC_JSC_UTILS_H_ +#define FLUTTER_UNICORN_RUNTIME_JSC_JSC_UTILS_H_ + +#include +#include +#include +#include + +#include "JavaScriptCore/JavaScript.h" +#include "js_runtime/runtime/runtime_values.h" + +namespace unicorn { + +class Conversion { + public: + static JSValueRef RuntimeValueToJSValue(JSContextRef ctx, + JSClassRef class_ref, + const RuntimeValues* value); + + static ScopeValues JSValueToRuntimeValue(JSContextRef ctx, + JSObjectRef thiz, + JSValueRef value); + + static void JSValuesArrayToRuntimeValues(JSContextRef ctx, JSObjectRef thiz, + size_t argc, const JSValueRef* argv, + std::vector& output); + + + static bool JSValueToStdString(JSContextRef ctx, JSValueRef value,std::string* result); + + static void printJSValueRefException(JSContextRef context,JSValueRef exc); + + + static JSValueRef ParserUtf8CharJsonToJValueJSContextRef(JSContextRef ctx, const char* utf_8_str); + +protected: + static ScopeValues JSValueToRuntimeValueWithCircleCheck(JSContextRef ctx, + JSObjectRef thiz, + JSValueRef value, + std::vector &stack_record, std::string &exception + ); +}; + +class JSUtils { + public: + static bool HasProperty(JSContextRef ctx, JSObjectRef ob, + const std::string& name); + static void SetProperty(JSContextRef ctx, JSObjectRef ob, + JSClassRef clz, const std::string& name, + RuntimeValues* value); + static ScopeValues GetProperty(JSContextRef ctx, JSObjectRef ob, + const std::string& name); + static bool DeleteProperty(JSContextRef ctx, JSObjectRef ob, + const std::string& name); + static void GetPropertyNameArray(JSContextRef ctx, JSObjectRef ob, + std::vector& native_array); + static ScopeValues CallAsFunction(JSContextRef ctx, JSObjectRef thiz, + JSObjectRef function, + size_t argc, const JSValueRef argv[]); +}; + +} // namespace unicorn + +#endif // FLUTTER_UNICORN_RUNTIME_JSC_JSC_UTILS_H_ diff --git a/weex_core/Source/js_runtime/runtime/jsc/runtime_object_jsc.cc b/weex_core/Source/js_runtime/runtime/jsc/runtime_object_jsc.cc new file mode 100644 index 0000000000..aa24575527 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/jsc/runtime_object_jsc.cc @@ -0,0 +1,80 @@ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#include "js_runtime/runtime/runtime_object.h" + +#include "js_runtime/runtime/jsc/jsc_utils.h" +#include "js_runtime/utils/log_utils.h" + +namespace unicorn { + +RuntimeObject::~RuntimeObject() { + if (nullptr != this->object_ && nullptr != this->context_){ + JSObjectSetPrivate(object_,nullptr); + } + //LOGE("[release] ~RuntimeObject() this:%p", this); +} + +void RuntimeObject::SetParentJSClass(JSRunTimeClass parent_class) { + parent_class_ = parent_class; +} + +bool RuntimeObject::HasProperty(const std::string& name) { + if (engine_context_) { + return JSUtils::HasProperty(context_, object_, name); + } + return false; +} + +void RuntimeObject::SetProperty(const std::string& name, JSRunTimeClass class_ref, + ScopeValues value) { + if (HasProperty(name)) + return; + + JSUtils::SetProperty(context_, object_, + class_ref, name, value.get()); +} + +void RuntimeObject::SetProperty(const std::string& name, RuntimeObject* value) { + if (value == nullptr || HasProperty(name) || engine_context_ == nullptr) + return; + + auto holder = RuntimeValues::MakeCommonObject( + static_cast(value), nullptr); + SetProperty(name, value->GetJSClass(), std::move(holder)); +} + +ScopeValues RuntimeObject::GetPropertyValue(const std::string& name) { + if (!HasProperty(name)) + return RuntimeValues::MakeUndefined(); + + return JSUtils::GetProperty(context_, object_, name); +} + +void RuntimeObject::GetPropertyNameArray(std::vector& array) { + if (engine_context_ == nullptr) + return; + JSUtils::GetPropertyNameArray(context_, object_, array); +} + +bool RuntimeObject::DeleteProperty(const std::string& name) { + if (!HasProperty(name)) + return false; + + return JSUtils::DeleteProperty(context_, object_, name); +} + +} // namespace unicorn diff --git a/weex_core/Source/js_runtime/runtime/jsc/runtime_values_jsc.cc b/weex_core/Source/js_runtime/runtime/jsc/runtime_values_jsc.cc new file mode 100644 index 0000000000..eb41a5b12f --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/jsc/runtime_values_jsc.cc @@ -0,0 +1,202 @@ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#include "js_runtime/runtime/jsc/runtime_values_jsc.h" + +#include "js_runtime/runtime/engine_context.h" +#include "js_runtime/runtime/jsc/jsc_utils.h" +#include "js_runtime/runtime/runtime_object.h" +#include "js_runtime/runtime/runtime_values.h" +#include "js_runtime/runtime/runtime_vm.h" +#include "js_runtime/utils/log_utils.h" + +namespace unicorn { + +///////////////////////////////////////////////////////////////////////////// +/* class JSCFunction implemention */ +std::unique_ptr +JSCFunction::CreateWithCallback(JSContextRef ctx, std::string name, + JSObjectRef thiz, + JSObjectCallAsFunctionCallback callback) { + Function* ptr = static_cast(new JSCFunction(ctx, name, + thiz, callback)); + return std::unique_ptr(ptr); +} + +std::unique_ptr +JSCFunction::Create(JSContextRef ctx, std::string name, + JSObjectRef thiz, JSObjectRef function) { + Function* ptr = static_cast(new JSCFunction(ctx, name, + thiz, function)); + return std::unique_ptr(ptr); +} + +JSCFunction::JSCFunction(JSContextRef ctx, std::string name, JSObjectRef thiz, + JSObjectCallAsFunctionCallback callback) + : Function(), + context_(ctx), + function_name_(name), + thiz_(thiz), + is_from_native_(true) { + if (thiz_ == nullptr) { + thiz_ = JSContextGetGlobalObject(ctx); + } + + JSStringRef str = JSStringCreateWithUTF8CString(function_name_.c_str()); + function_ = JSObjectMakeFunctionWithCallback(context_, str, callback); + JSObjectSetProperty(context_, thiz_, str, function_, 0, nullptr); + JSStringRelease(str); + + JSGlobalContextRef global_ctx = JSContextGetGlobalContext(ctx); + EngineContext* context = + RuntimeVM::GetEngineContext(static_cast(global_ctx)); + RuntimeObject* native_thiz = new RuntimeObject(context); + native_thiz->SetJSObject(function_); + Function::SetObject(native_thiz); + + MemberProtect(); +} + +JSCFunction::JSCFunction(JSContextRef ctx, std::string name, JSObjectRef thiz, + JSObjectRef function) + : context_(ctx), + function_name_(name), + thiz_(thiz), + function_(function), + is_from_native_(false) { + context_ = JSContextGetGlobalContext(ctx); + // LOG_JS_RUNTIME("JSCFunction constructor,ctx:%p, thiz:%p,func:%p",context_,thiz_,function_); + JSGlobalContextRef global_ctx = JSContextGetGlobalContext(ctx); + EngineContext* context = + RuntimeVM::GetEngineContext(static_cast(global_ctx)); + RuntimeObject* native_thiz = new RuntimeObject(context); + native_thiz->SetJSObject(function_); + Function::SetObject(native_thiz); + + MemberProtect(); +} + +JSCFunction::~JSCFunction() { + MemberUnprotect(); +} + +void JSCFunction::MemberProtect() { + JSValueProtect(context_, thiz_); + JSValueProtect(context_, function_); +} + +void JSCFunction::MemberUnprotect() { + JSValueUnprotect(context_, thiz_); + JSValueUnprotect(context_, function_); +} + +std::unique_ptr JSCFunction::Call(JSContextRef cur_context,size_t argc, + std::vector& argv) const { + LOG_RUNTIME("call js on context:%p",cur_context); + JSValueRef argv_js[argc]; + for (size_t i = 0; i < argc; i++) { +// LOG_TEST("[Context] JSCFunction Call func originContext :%p",context_); +// auto excute = toJS(context_); +// LOG_TEST("[Context] JSCFunction Call func excute :%p",excute); +// auto newConText = toRef(excute); +// LOG_TEST("[Context] JSCFunction Call func newConText :%p",newConText); + + + +// LOG_TEST("[Context] JSCFunction Call func: cur_ctx:%p,self_context:%p thiz:%p,",cur_context,context_,thiz_); + argv_js[i] = Conversion::RuntimeValueToJSValue(cur_context, nullptr, + argv[i].get()); + } + + return JSUtils::CallAsFunction(static_cast(cur_context), + static_cast(thiz_), + static_cast(function_), + argc, argv_js); +} + +///////////////////////////////////////////////////////////////////////////// +/* class JSCMap implemention */ +std::unique_ptr JSCMap::Create(JSContextRef ctx, JSObjectRef thiz) { + Map* ptr = static_cast(new JSCMap(ctx, thiz)); + return std::unique_ptr(ptr); +} + +// Map create from native +std::unique_ptr Map::CreateFromNative(EngineContext* context, + ScopeValues thiz) { + JSContextRef ctx = static_cast(context->GetContext()); + JSObjectRef thiz_object = nullptr; + if (thiz->IsObject()) { + auto object = thiz->GetAsObject(); + RuntimeObject* native_thiz = + static_cast(object->GetDataPtr()); + thiz_object = native_thiz->GetJSObject(); + } + return JSCMap::Create(ctx, thiz_object); +} + +JSCMap::JSCMap(JSContextRef ctx, JSObjectRef thiz) + : Map(), + context_(ctx), + thiz_(thiz) { + JSValueProtect(context_, thiz_); +} + +JSCMap::~JSCMap() { + JSValueUnprotect(context_, thiz_); +} + +///////////////////////////////////////////////////////////////////////////// +std::unique_ptr Array::CreateFromNative(EngineContext* context, + ScopeValues thiz){ + JSContextRef ctx = static_cast(context->GetContext()); + JSObjectRef thiz_object = nullptr; + if (thiz->IsObject()) { + auto object = thiz->GetAsObject(); + RuntimeObject* native_thiz = static_cast(object->GetDataPtr()); + thiz_object = native_thiz->GetJSObject(); + } + return JSCArray::Create(ctx, thiz_object); +} + + + +/* class JSCArray implemention */ +std::unique_ptr JSCArray::Create(JSContextRef ctx, JSObjectRef thiz) { + //LOG_TEST("JSCArray before Create"); + Array* ptr = static_cast(new JSCArray(ctx, thiz)); + //LOG_TEST("JSCArray after Create"); + return std::unique_ptr(ptr); +} + +JSCArray::JSCArray(JSContextRef ctx, JSObjectRef thiz) + : Array(), context_(ctx), thiz_(thiz) { + //LOG_TEST("JSCArray before JSValueProtect ctx:%p , thiz:%p",context_,thiz_); + if (nullptr != ctx && nullptr != thiz){ + JSValueProtect(context_, thiz_); + } + // + //LOG_TEST("JSCArray after JSValueProtect "); +} + +JSCArray::~JSCArray() { + if (nullptr != context_ && nullptr != thiz_){ + JSValueUnprotect(context_, thiz_); + } + //JSValueUnprotect(context_, thiz_); +} + +} // namespace unicorn diff --git a/weex_core/Source/js_runtime/runtime/jsc/runtime_values_jsc.h b/weex_core/Source/js_runtime/runtime/jsc/runtime_values_jsc.h new file mode 100644 index 0000000000..f5002458ef --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/jsc/runtime_values_jsc.h @@ -0,0 +1,113 @@ +/** + * 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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_JSC_RUNTIME_VALUES_JSC_H_ +#define FLUTTER_UNICORN_RUNTIME_JSC_RUNTIME_VALUES_JSC_H_ + +#include +#include +#include +#include +#include + +#include "JavaScriptCore/JavaScript.h" +#include "js_runtime/runtime/runtime_values.h" +#include "JavaScriptCore/JSObjectRef.h" +namespace unicorn { + +class JSCFunction : public Function { + public: + static std::unique_ptr + CreateWithCallback(JSContextRef ctx, std::string name, + JSObjectRef thiz, + JSObjectCallAsFunctionCallback callback); + + static std::unique_ptr Create(JSContextRef ctx, std::string name, + JSObjectRef thiz, JSObjectRef function); + + JSCFunction(JSContextRef ctx, std::string name, JSObjectRef thiz, + JSObjectCallAsFunctionCallback callback); + + JSCFunction(JSContextRef ctx, std::string name, JSObjectRef thiz, + JSObjectRef function); + ~JSCFunction(); + + bool IsFromNative() override { return is_from_native_; }; + + std::unique_ptr Call(JSContextRef cur_context,size_t argc, + std::vector& argv) const override; + + JSObjectRef GetFunction() const { return function_; } + + private: + void MemberProtect(); + void MemberUnprotect(); + + JSContextRef context_; + std::string function_name_; + JSObjectRef thiz_; + JSObjectRef function_; + bool is_from_native_; +}; + +class JSCMap : public Map { + public: + static std::unique_ptr Create(JSContextRef ctx, JSObjectRef thiz); + + JSCMap(JSContextRef ctx, JSObjectRef thiz); + ~JSCMap(); + + JSObjectRef GetThisObject() const { return thiz_; } + + private: + JSContextRef context_; + JSObjectRef thiz_; +}; + +class JSCArray : public Array { + public: + static std::unique_ptr Create(JSContextRef ctx, JSObjectRef thiz); + + JSCArray(JSContextRef ctx, JSObjectRef thiz); + ~JSCArray(); + + JSObjectRef GetThisObject() const { return thiz_; } + + private: + JSContextRef context_; + JSObjectRef thiz_; +}; + +} // namespace unicorn +#endif // FLUTTER_UNICORN_RUNTIME_JSC_RUNTIME_VALUES_JSC_H_ diff --git a/weex_core/Source/js_runtime/runtime/jsc/vm_jsc.cc b/weex_core/Source/js_runtime/runtime/jsc/vm_jsc.cc new file mode 100644 index 0000000000..eecf75fd9b --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/jsc/vm_jsc.cc @@ -0,0 +1,68 @@ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ +#include + +#include +#include "js_runtime/runtime/engine_context.h" +#include "js_runtime/runtime/runtime_context.h" +#include "js_runtime/runtime/runtime_vm.h" + +namespace unicorn { + +std::unordered_map g_context_map; + +// implemete engine vm create function +void* RuntimeVM::CreateEngineVM() { + // initialize jsc threading environment + // create vm + JSContextGroupRef context_group = JSContextGroupCreate(); + return static_cast(const_cast(context_group)); +} + +void RuntimeVM::ReleaseEngineVM(void* vm) { + if (vm == nullptr) return; + JSContextGroupRelease(static_cast(vm)); +} + +void RuntimeVM::NotifyContextCreated(RuntimeContext* context) { + if (context == nullptr) + return; + + EngineContext* engine_ctx = context->GetEngineContext(); + JSContextRef js_ctx = static_cast(engine_ctx->GetContext()); + g_context_map[js_ctx] = engine_ctx; +} + +void RuntimeVM::NotifyContextDestorying(RuntimeContext* context) { + if (context == nullptr) + return; + EngineContext* engine_ctx = context->GetEngineContext(); + JSContextRef js_ctx = static_cast(engine_ctx->GetContext()); + g_context_map.erase(js_ctx); +} + +EngineContext* RuntimeVM::GetEngineContext(const void* js_ctx) { + if (js_ctx == nullptr) + return nullptr; + + JSContextRef ctx = static_cast(js_ctx); + if (g_context_map.find(ctx) == g_context_map.end()) + return nullptr; + + return g_context_map[ctx]; +} + +} // namespace unicorn diff --git a/weex_core/Source/js_runtime/runtime/runtime_context.h b/weex_core/Source/js_runtime/runtime/runtime_context.h new file mode 100644 index 0000000000..910db2d47c --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/runtime_context.h @@ -0,0 +1,84 @@ +/** + * 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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_RUNTIME_CONTEXT_H_ +#define FLUTTER_UNICORN_RUNTIME_RUNTIME_CONTEXT_H_ + +#include +#include +#include + +#include "js_runtime/runtime/runtime_values.h" +#include "js_runtime/runtime/runtime_vm.h" + +namespace unicorn { +class EngineContext; + +class RuntimeContext { + public: + enum State { + Unknown, + Uninitialized, + Initialized, + Ready, + Running, + Destroyed, + }; +/** + * + * @param vm runtime vm + * @param globalObjectClass if not null,create as context's globalObject,else use default globalObject + * @return context + */ + static std::unique_ptr Create(RuntimeVM* vm,JSRunTimeClass globalObjectClass); + + virtual ~RuntimeContext() {} + virtual void CreateJavaScriptContext(JSRunTimeClass globalObjectClass) = 0; + virtual void ReleaseJavaScriptContext() = 0; + virtual void SetName(const std::string& name) = 0; + virtual void InitializeContext() = 0; + virtual EngineContext* GetEngineContext() const = 0; + virtual void UpdateSetting(const std::string& settings) = 0; + virtual bool ExecuteJavaScript(const std::string &content,std::string *exception) = 0; + virtual std::unique_ptr ExecuteJavaScriptWithResult(const std::string& name,std::string *exception) = 0; + //virtual JSRunTimeValue callJavaScriptFunc(RuntimeObject* target,const std::string& name,std::vector &args,std::string *exception) = 0; + + virtual void NotifyIdle() = 0; + virtual bool Available() = 0; + virtual void Destroy() = 0; +}; + +} // namespace unicorn + +#endif // FLUTTER_UNICORN_RUNTIME_RUNTIME_CONTEXT_H_ diff --git a/weex_core/Source/js_runtime/runtime/runtime_context_android.cc b/weex_core/Source/js_runtime/runtime/runtime_context_android.cc new file mode 100644 index 0000000000..414719e8cd --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/runtime_context_android.cc @@ -0,0 +1,79 @@ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#include "js_runtime/runtime/runtime_context_android.h" + +#include + +namespace unicorn { + + RuntimeContextAndroid::RuntimeContextAndroid(RuntimeVM *vm,JSRunTimeClass globalObjectClass) + : initialized_(false), vm_(vm), script_url_("") { + engine_context_.reset(EngineContext::CreateEngineContext(this, vm_,globalObjectClass)); + RuntimeVM::NotifyContextCreated(this); + } + + RuntimeContextAndroid::~RuntimeContextAndroid() { + RuntimeVM::NotifyContextDestorying(this); + if (engine_context_) { + engine_context_.reset(); + } + } + + void RuntimeContextAndroid::CreateJavaScriptContext(JSRunTimeClass globalObjectClass) { + engine_context_.reset(EngineContext::CreateEngineContext(this, vm_,globalObjectClass)); + RuntimeVM::NotifyContextCreated(this); + } + + void RuntimeContextAndroid::ReleaseJavaScriptContext() { + RuntimeVM::NotifyContextDestorying(this); + engine_context_.reset(); + } + + void RuntimeContextAndroid::SetName(const std::string &name) {} + + void RuntimeContextAndroid::InitializeContext() {} + + void RuntimeContextAndroid::UpdateSetting(const std::string &name) {} + + bool RuntimeContextAndroid::ExecuteJavaScript(const std::string &content,std::string *exception) { + return engine_context_->RunJavaScript(content,exception); + } + + ScopeValues RuntimeContextAndroid::ExecuteJavaScriptWithResult(const std::string &content,std::string *exception) { + return engine_context_->RunJavaScriptWithResult(content,exception); + } + + void RuntimeContextAndroid::OnEngineContextInitialized() { + if (!initialized_) initialized_ = true; + } + + void RuntimeContextAndroid::OnEngineContextFinalized() { initialized_ = false; } + + void RuntimeContextAndroid::NotifyIdle() { + // TODO(unicorn): we can do gc worker when idle + } + + bool RuntimeContextAndroid::Available() { return initialized_; } + + void RuntimeContextAndroid::Destroy() {} + + std::unique_ptr RuntimeContext::Create(RuntimeVM *vm,JSRunTimeClass globalObjectClass) { + return std::unique_ptr( + static_cast(new RuntimeContextAndroid(vm,globalObjectClass))); + } + +} // namespace unicorn diff --git a/weex_core/Source/js_runtime/runtime/runtime_context_android.h b/weex_core/Source/js_runtime/runtime/runtime_context_android.h new file mode 100644 index 0000000000..faae53f423 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/runtime_context_android.h @@ -0,0 +1,80 @@ +/** + * 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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_RUNTIME_CONTEXT_ANDROID_H_ +#define FLUTTER_UNICORN_RUNTIME_RUNTIME_CONTEXT_ANDROID_H_ + +#include +#include + +#include "js_runtime/runtime/engine_context.h" +#include "js_runtime/runtime/runtime_vm.h" +#include "js_runtime/runtime/runtime_context.h" + +namespace unicorn { + +class RuntimeContextAndroid : public RuntimeContext, EngineContextDelegate { + public: + explicit RuntimeContextAndroid(RuntimeVM* vm,JSRunTimeClass globalObjectClass); + ~RuntimeContextAndroid() override; + + // override RuntimeContext + void CreateJavaScriptContext(JSRunTimeClass globalClass) override; + void ReleaseJavaScriptContext() override; + void SetName(const std::string& name) override; + void InitializeContext() override; + void UpdateSetting(const std::string& settings) override; + bool ExecuteJavaScript(const std::string &content,std::string *exception) override; + ScopeValues ExecuteJavaScriptWithResult(const std::string &content,std::string *exception) override; + + EngineContext* GetEngineContext() const override { return engine_context_.get(); } + + // override EngineContextDelegate + void OnEngineContextInitialized() override; + void OnEngineContextFinalized() override; + + void NotifyIdle() override; + bool Available() override; + void Destroy() override; + + private: + bool initialized_; + RuntimeVM* vm_; + std::string script_url_; + std::unique_ptr engine_context_; +}; + +} // namespace unicorn + +#endif // FLUTTER_UNICORN_RUNTIME_RUNTIME_CONTEXT_ANDROID_H_ diff --git a/weex_core/Source/js_runtime/runtime/runtime_context_ios.h b/weex_core/Source/js_runtime/runtime/runtime_context_ios.h new file mode 100644 index 0000000000..9d4f9fa3c4 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/runtime_context_ios.h @@ -0,0 +1,79 @@ +/** + * 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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_RUNTIME_CONTEXT_IOS_H_ +#define FLUTTER_UNICORN_RUNTIME_RUNTIME_CONTEXT_IOS_H_ + +#include +#include + +#include "js_runtime/runtime/engine_context.h" +#include "js_runtime/runtime/runtime_context.h" +#include "js_runtime/runtime/runtime_vm.h" + +namespace unicorn { + +class RuntimeContextIOS : public RuntimeContext, EngineContextDelegate { + public: + explicit RuntimeContextIOS(RuntimeVM* vm); + ~RuntimeContextIOS(); + + void CreateJavaScriptContext() override; + void ReleaseJavaScriptContext() override; + void SetName(const std::string& name) override; + void InitializeContext() override; + void UpdateSetting(const std::string& settings) override; + bool ExecuteJavaScript(const std::string& name) override; + std::unique_ptr ExecuteJavaScriptWithResult( + const std::string& name) override; + + EngineContext* GetEngineContext() const override { + return engine_context_.get(); } + + void NotifyIdle() override; + bool Available() override; + void Destroy() override; + + // override EngineContextDelegate + void OnEngineContextInitialized() override; + void OnEngineContextFinalized() override; + + private: + RuntimeVM* vm_; + bool initialized_; + std::unique_ptr engine_context_; +}; + +} // namespace unicorn +#endif // FLUTTER_UNICORN_RUNTIME_RUNTIME_CONTEXT_IOS_H_ diff --git a/weex_core/Source/js_runtime/runtime/runtime_context_ios.mm b/weex_core/Source/js_runtime/runtime/runtime_context_ios.mm new file mode 100644 index 0000000000..c497106dfc --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/runtime_context_ios.mm @@ -0,0 +1,79 @@ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#include "js_runtime/runtime/runtime_context_ios.h" + +#include + +namespace unicorn { + +RuntimeContextIOS::RuntimeContextIOS(RuntimeVM* vm) : vm_(vm), initialized_(false) { + CreateJavaScriptContext(); +} + +RuntimeContextIOS::~RuntimeContextIOS() { vm_ = nullptr; } + +void RuntimeContextIOS::CreateJavaScriptContext() { + // TODO + engine_context_.reset(EngineContext::CreateEngineContext(this, vm_)); + RuntimeVM::NotifyContextCreated(this); +} + +void RuntimeContextIOS::ReleaseJavaScriptContext() { + RuntimeVM::NotifyContextDestorying(this); + engine_context_.reset(); +} + +void RuntimeContextIOS::SetName(const std::string& name) {} + +void RuntimeContextIOS::InitializeContext() {} + +void RuntimeContextIOS::UpdateSetting(const std::string& name) {} + +bool RuntimeContextIOS::ExecuteJavaScript(const std::string& content) { + if (!engine_context_) + return false; + engine_context_->RunJavaScript(content); + return true; +} + +std::unique_ptr RuntimeContextIOS::ExecuteJavaScriptWithResult( + const std::string& content) { + // TODO + return std::make_unique( + new RuntimeValues(nullptr)); +} + +void RuntimeContextIOS::NotifyIdle() {} + +bool RuntimeContextIOS::Available() { + return engine_context_ ? true : false ; +} + +void RuntimeContextIOS::Destroy() {} + +void RuntimeContextIOS::OnEngineContextInitialized() { + if (!initialized_) initialized_ = true; +} + +void RuntimeContextIOS::OnEngineContextFinalized() { initialized_ = false; } + +std::unique_ptr RuntimeContext::Create(RuntimeVM* vm) { + return std::unique_ptr( + static_cast(new RuntimeContextIOS(vm))); +} + +} // namespace unicorn diff --git a/weex_core/Source/js_runtime/runtime/runtime_object.h b/weex_core/Source/js_runtime/runtime/runtime_object.h new file mode 100644 index 0000000000..7bbba53574 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/runtime_object.h @@ -0,0 +1,93 @@ +/** + * 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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_RUNTIME_OBJECT_H_ +#define FLUTTER_UNICORN_RUNTIME_RUNTIME_OBJECT_H_ + +#include +#include +#include "js_runtime/runtime/engine_context.h" +#include "js_runtime/runtime/runtime_values.h" +#include "JavaScriptCore/JSObjectRef.h" + + +namespace unicorn { + +class RuntimeObject { + public: + explicit RuntimeObject(EngineContext* context, JSRunTimeContext js_ctx = nullptr) + : engine_context_(context) { + // if js_ctx is null, so we use global context + if (js_ctx == nullptr && engine_context_) + context_ = static_cast(engine_context_->GetContext()); + else + context_ = js_ctx; + } + virtual ~RuntimeObject(); + + virtual void SetEngineContext(EngineContext* context) { + engine_context_ = context; + if (context_ == nullptr && context) + context_ = static_cast(engine_context_->GetContext()); + } + virtual EngineContext* GetEngineContext() const { return engine_context_; } + virtual void SetParentJSClass(JSRunTimeClass parent_class); + virtual JSRunTimeClass ParentJSClass() { return parent_class_; } + virtual void SetJSClass(JSRunTimeClass class_ref) { class_ = class_ref; } + virtual JSRunTimeClass GetJSClass() { return class_; } + virtual void SetJSObject(JSRunTimeObject object) { object_ = object;} + virtual JSRunTimeObject GetJSObject() { return object_; } + virtual bool HasProperty(const std::string& name); + virtual void SetProperty(const std::string& name, JSRunTimeClass clz, + ScopeValues value); + virtual void SetProperty(const std::string& name, RuntimeObject* value); + virtual ScopeValues GetPropertyValue(const std::string& name); + virtual void GetPropertyNameArray(std::vector& array); + virtual bool DeleteProperty(const std::string& name); + // this function is used after your member functuon called by javascript + // if you want to do something to the jsobject, please override this + // funciton + virtual void OnMethodCalledByJS() {} + + private: + EngineContext* engine_context_; + JSRunTimeClass parent_class_{nullptr}; + JSRunTimeClass class_{nullptr}; + JSRunTimeObject object_{nullptr}; + JSRunTimeContext context_{nullptr}; +}; + +} // namespace unicorn + +#endif // FLUTTER_UNICORN_RUNTIME_RUNTIME_OBJECT_H_ diff --git a/weex_core/Source/js_runtime/runtime/runtime_values.cc b/weex_core/Source/js_runtime/runtime/runtime_values.cc new file mode 100644 index 0000000000..75a6f61ac4 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/runtime_values.cc @@ -0,0 +1,265 @@ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#include "js_runtime/runtime/runtime_values.h" +#include + +#include "js_runtime/runtime/runtime_object.h" +#include "js_runtime/utils/log_utils.h" + +namespace unicorn { + + Map::~Map() { + for (auto &iter : properties_) { + delete iter.second; + } + } + + Array::~Array() { + for (size_t i = 0; i < Size(); i++) { + delete values_[i]; + } + } + + Function::~Function() { + if (this_object_) + delete this_object_; + } + + void Function::SetObject(RuntimeObject *thiz) { + this_object_ = thiz; + } + + RuntimeValues::RuntimeValues(RuntimeValues &&origin) { + InternalMoveConstructFrom(std::move(origin)); + } + + void RuntimeValues::InternalMoveConstructFrom(RuntimeValues &&that) { + type_ = that.type_; + + switch (type_) { + case Type::UNDEFINED: + return; + case Type::NULLVALUE: + return; + case Type::BOOLEAN: + data_.bool_value_ = that.data_.bool_value_; + return; + case Type::INTEGER: + data_.int_value_ = that.data_.int_value_; + return; + case Type::DOUBLE: + data_.double_value_ = that.data_.double_value_; + return; + case Type::STRING: + new(&data_.string_value_) std::string( + std::move(that.data_.string_value_)); + break; + case Type::OBJECT: + common_object_ = std::move(that.common_object_); + break; + case Type::FUNCTION: + function_ = std::move(that.function_); + break; + case Type::MAP: + map_ = std::move(that.map_); + break; + case Type::ARRAY: + array_ = std::move(that.array_); + case Type::JSONObject: + data_.string_value_=that.data_.string_value_; + break; + } + } + + RuntimeValues::RuntimeValues(bool in_bool) : type_(Type::BOOLEAN) { + data_.bool_value_ = in_bool; + } + + RuntimeValues::RuntimeValues(int in_int) : type_(Type::INTEGER) { + data_.int_value_ = in_int; + } + + RuntimeValues::RuntimeValues(double in_double) : type_(Type::DOUBLE) { + data_.double_value_ = in_double; + } + + RuntimeValues::RuntimeValues(const char *in_string, size_t length) + : type_(Type::STRING) { + data_.string_value_ = std::string(in_string, length); + } + + RuntimeValues::RuntimeValues(const std::string &in_string) + : type_(Type::STRING) { + data_.string_value_ = in_string; + // new(&data_.string_value_) std::string(in_string); + } + + RuntimeValues::RuntimeValues(const std::string &in_string,Type type){ + data_.string_value_ = in_string; + type_ = type; + // new(&data_.string_value_) std::string(in_string); + } + + RuntimeValues::RuntimeValues(std::unique_ptr object) + : type_(Type::OBJECT), + common_object_(std::move(object)) { + } + + RuntimeValues::RuntimeValues(std::unique_ptr map) + : type_(Type::MAP) { + map_ = std::move(map); + } + + RuntimeValues::RuntimeValues(std::unique_ptr func) + : type_(Type::FUNCTION) { + function_ = std::move(func); + } + + RuntimeValues::RuntimeValues(std::unique_ptr array) + : type_(Type::ARRAY) { + array_ = std::move(array); + } + + RuntimeValues &RuntimeValues::operator=(RuntimeValues &&that) { + if (this == &that) + return *this; + + InternalMoveConstructFrom(std::move(that)); + + return *this; + } + + RuntimeValues::~RuntimeValues() { + } + + void RuntimeValues::SetValue(std::unique_ptr &&value) {} + + void RuntimeValues::SetType(Type type) { + if (common_object_) { + switch (type) { + case Type::UNDEFINED: + break; + case Type::NULLVALUE: + break; + case Type::BOOLEAN: { + Object *origin_b = static_cast(common_object_.release()); + data_.bool_value_ = *(static_cast(origin_b->GetDataPtr())); + } + break; + case Type::INTEGER: { + Object *origin_i = static_cast(common_object_.release()); + data_.int_value_ = *(static_cast(origin_i->GetDataPtr())); + } + break; + case Type::DOUBLE: { + Object *origin_d = static_cast(common_object_.release()); + data_.double_value_ = *(static_cast( + origin_d->GetDataPtr())); + } + break; + case Type::STRING: { + Object *origin_s = static_cast(common_object_.release()); + data_.string_value_ = *(static_cast( + origin_s->GetDataPtr())); + } + break; + case Type::OBJECT: + break; + case Type::FUNCTION: + break; + case Type::MAP: + break; + case Type::ARRAY: + break; + default: + break; + } + } + type_ = type; + } + + bool RuntimeValues::GetAsBoolean(bool *out_value) const { + if (IsBool()) { + *out_value = data_.bool_value_; + return true; + } + + return false; + } + + bool RuntimeValues::GetAsInteger(int *out_value) const { + if (IsDouble()) { + *out_value = static_cast(data_.double_value_); + return true; + } + if (IsInt()) { + *out_value = data_.int_value_; + return true; + } + + return false; + } + + bool RuntimeValues::GetAsDouble(double *out_value) const { + if (IsDouble()) { + *out_value = data_.double_value_; + return true; + } + if (IsInt()) { + *out_value = static_cast(data_.int_value_); + return true; + } + + return false; + } + + bool RuntimeValues::GetAsUtf8JsonStr(std::string &out_value) const { + if (IsJsonObject()) { + out_value.assign(data_.string_value_); + return true; + } + return false; + } + + + bool RuntimeValues::GetAsString(std::string *out_value) const { + if (IsString()) { + out_value->assign(data_.string_value_); + return true; + } + + return false; + } + + BaseObject *RuntimeValues::GetAsObject() const { + if (IsObject()) { + return common_object_.get(); + } + + return nullptr; + } + + + BaseObject *RuntimeValues::PassObject() { + if (IsObject()) { + return common_object_.release(); + } + + return nullptr; + } + +} // namespace unicorn diff --git a/weex_core/Source/js_runtime/runtime/runtime_values.h b/weex_core/Source/js_runtime/runtime/runtime_values.h new file mode 100644 index 0000000000..8b53fb3025 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/runtime_values.h @@ -0,0 +1,390 @@ +/** + * 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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_RUNTIME_VALUES_H_ +#define FLUTTER_UNICORN_RUNTIME_RUNTIME_VALUES_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "js_runtime/runtime/base.h" + + +namespace unicorn { + +class EngineContext; +class RuntimeObject; +class RuntimeValues; + +typedef std::unique_ptr ScopeValues; + +class RuntimeClass { + public: + explicit RuntimeClass(JSRunTimeClass clasz) : clasz_(clasz) {} + ~RuntimeClass() = default; + JSRunTimeClass GetJSClass() const { return clasz_; } + + private: + JSRunTimeClass clasz_; +}; + +class BaseObject { + public: + virtual ~BaseObject() = default; + virtual void* GetDataPtr() = 0; + virtual RuntimeClass* GetRuntimeClass() = 0; +}; + +class Object : public BaseObject { + public: + static std::unique_ptr MakeObject(void* ptr, + RuntimeClass* clasz) { + return std::unique_ptr(static_cast( + new Object(ptr, clasz))); + } + + Object(void* ptr, RuntimeClass* clasz) + : ptr_(ptr), + clasz_(clasz) { + } + + // move constructor + Object(Object&& other) : ptr_(other.ptr_) { + other.Clear(); + } + + Object& operator=(Object&& other) { + this->ptr_ = other.GetDataPtr(); + other.Clear(); + return *this; + } + + ~Object() { ptr_ = nullptr; } + + void* GetDataPtr() override { return ptr_; } + RuntimeClass* GetRuntimeClass() override { return clasz_.get(); } + void Clear() { ptr_ = nullptr; } + + private: + void* ptr_; + std::unique_ptr clasz_; +}; + +class Function { + public: + virtual ~Function(); + virtual bool IsFromNative() = 0; + virtual std::unique_ptr Call(JSRunTimeContext cur_context,size_t argc, + std::vector& argv) const = 0; + + RuntimeObject* GetObject() const { return this_object_; } + void SetObject(RuntimeObject* thiz); + + private: + RuntimeObject* this_object_{nullptr}; +}; + +class Map { + public: + static std::unique_ptr CreateFromNative(EngineContext* context, + ScopeValues thiz); + + virtual ~Map(); + + size_t Size() { return properties_.size(); } + + void Clear() noexcept { + properties_.clear(); + } + + void Insert(const std::string& name, RuntimeValues* value) { + properties_[name] = value; + } + + void Remove(const std::string& name) { + properties_.erase(name); + } + + RuntimeValues* operator[] (std::string name) { + return properties_[name]; + } + +// const RuntimeValues* get(const std::string & name) const{ +// return properties_[name]; +// } + + const std::unordered_map& GetMap() const { + return properties_; + } + + private: + std::unordered_map properties_; +}; + +class Array { + public: + + static std::unique_ptr CreateFromNative(EngineContext* context, + ScopeValues thiz); + Array() = default; + virtual ~Array(); + + bool Empty() { return values_.empty(); } + size_t Size() const { return values_.size(); } + RuntimeValues* Front() { return values_.front(); } + RuntimeValues* Back() { return values_.back(); } + void PushBack(RuntimeValues* value) { values_.push_back(value); } + void PopBack() { values_.pop_back(); } + + RuntimeValues* atIndex(size_t index) const { return values_[index];} + + RuntimeValues* operator[](size_t index) { return values_[index]; } + const std::vector& GetArray() const { return values_; } + + private: + std::vector values_; +}; + +class RuntimeValues { + public: + enum class Type { + UNDEFINED = 0, + NULLVALUE, + BOOLEAN, + INTEGER, + DOUBLE, + STRING, + FUNCTION, + OBJECT, + MAP, + ARRAY, + JSONObject + }; + + RuntimeValues(RuntimeValues&& other); + RuntimeValues& operator=(RuntimeValues&& that); + + void InternalMoveConstructFrom(RuntimeValues&& that); + + RuntimeValues() : type_(Type::UNDEFINED) {} + + explicit RuntimeValues(std::nullptr_t) : type_(Type::NULLVALUE) { + } + explicit RuntimeValues(bool in_bool); + explicit RuntimeValues(int in_int); + explicit RuntimeValues(double in_double); + explicit RuntimeValues(const char* in_string, size_t length); + explicit RuntimeValues(const std::string& in_string); + explicit RuntimeValues(std::unique_ptr object); + explicit RuntimeValues(std::unique_ptr map); + explicit RuntimeValues(std::unique_ptr func); + explicit RuntimeValues(std::unique_ptr array); + //json or other storage with string + explicit RuntimeValues(const std::string &in_string,Type type); + + RuntimeValues& operator=(const RuntimeValues& that) = delete; + RuntimeValues(const RuntimeValues& that) = delete; + + ~RuntimeValues(); + + static ScopeValues MakeUndefined() { + return ScopeValues(new RuntimeValues()); + } + + static ScopeValues MakeNull() { + return ScopeValues(new RuntimeValues(nullptr)); + } + + static ScopeValues MakeBool(bool in_bool) { + return ScopeValues(new RuntimeValues(in_bool)); + } + + static ScopeValues MakeInt(int in_int) { + return ScopeValues(new RuntimeValues(in_int)); + } + + static ScopeValues MakeDouble(double in_double) { + return ScopeValues(new RuntimeValues(in_double)); + } + +// static ScopeValues MakeString(const char* in_str) { +// std::string tmp(in_str); +// return ScopeValues(new RuntimeValues(tmp)); +// } + + static ScopeValues MakeString(const std::string& in_string) { + return ScopeValues(new RuntimeValues(in_string)); + } + + static ScopeValues MakeCommonObject(void* ptr, RuntimeClass* clasz) { + auto object = Object::MakeObject(ptr, clasz); + return ScopeValues(new RuntimeValues(std::move(object))); + } + + static ScopeValues MakeCommonObject(std::unique_ptr object) { + return ScopeValues(new RuntimeValues(std::move(object))); + } + + static ScopeValues MakeMap(std::unique_ptr map) { + return ScopeValues(new RuntimeValues(std::move(map))); + } + + static ScopeValues MakeFunction(std::unique_ptr func) { + return ScopeValues(new RuntimeValues(std::move(func))); + } + + static ScopeValues MakeArray(std::unique_ptr array) { + return ScopeValues(new RuntimeValues(std::move(array))); + } + + static ScopeValues MakeObjectFromJsonStr(const std::string &utf_8_json_str) { + return ScopeValues(new RuntimeValues(utf_8_json_str,Type::JSONObject)); + } + + + void SetValue(std::unique_ptr&& value); + + void SetType(Type type); + Type GetType() const { return type_; } + + size_t GetLength(); + bool IsUndefined() const { return type_ == Type::UNDEFINED; } + bool IsBool() const { return type_ == Type::BOOLEAN; } + bool IsInt() const { return type_ == Type::INTEGER; } + bool IsDouble() const { return type_ == Type::DOUBLE; } + bool IsNumber() const { return IsInt() || IsDouble(); } + bool IsString() const { return type_ == Type::STRING; } + bool IsFunction() const { return type_ == Type::FUNCTION; } + bool IsObject() const { return type_ == Type::OBJECT; } + bool IsMap() const { return type_ == Type::MAP; } + bool IsArray() const { return type_ == Type::ARRAY; } + bool IsNull() const { return type_ == Type::NULLVALUE; } + bool IsJsonObject() const { return type_ == Type::JSONObject; } + + // get from union + bool GetAsBoolean(bool* out_val) const; + bool GetAsInteger(int* out_val) const; + bool GetAsDouble(double* out_val) const; + bool GetAsString(std::string* out_val) const; + bool GetAsUtf8JsonStr(std::string &json_val) const; + const Map* GetAsMap() const { return map_.get(); } + const Array* GetAsArray() const { return array_.get(); } + Function* GetAsFunction() const { return function_.get(); } + + BaseObject* GetAsObject() const; + BaseObject* PassObject(); + + operator int() const { + if (IsNumber()) { + int r = 0; + GetAsInteger(&r); + return r; + } + abort(); + return 0; + } + + operator double() const { + if (IsNumber()) { + double r = 0.0; + GetAsDouble(&r); + return r; + } + abort(); + return 0.0; + } + + operator bool() const { + if (IsBool()) { + bool r = false; + GetAsBoolean(&r); + return r; + } + abort(); + return false; + } + + operator std::string() const { + if (IsString()) { + std::string str; + GetAsString(&str); + return str; + } + abort(); + return ""; + } + + Type type_; + + struct Data { + bool bool_value_; + int int_value_; + double double_value_; + std::string string_value_; + }; + + private: + std::unique_ptr common_object_; + std::unique_ptr map_; + std::unique_ptr function_; + std::unique_ptr array_; + Data data_; +}; + +template +static auto ToRuntimeValues(void* object, std::string name) { + using Type = typename std::remove_reference::type; + + auto holder = Object::MakeObject(object, nullptr); + auto value = RuntimeValues::MakeCommonObject(std::move(holder)); + if (std::is_integral::value) { + value->SetType(RuntimeValues::Type::INTEGER); + } + if (std::is_floating_point::value) { + value->SetType(RuntimeValues::Type::DOUBLE); + } + if (std::is_same::value) { + value->SetType(RuntimeValues::Type::STRING); + } + + return value; +} + +} // namespace unicorn +#endif // FLUTTER_UNICORN_RUNTIME_RUNTIME_VALUES_H_ diff --git a/weex_core/Source/js_runtime/runtime/runtime_vm.cc b/weex_core/Source/js_runtime/runtime/runtime_vm.cc new file mode 100644 index 0000000000..84d3b730e8 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/runtime_vm.cc @@ -0,0 +1,58 @@ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#include "js_runtime/runtime/runtime_vm.h" + +#include +#include +#include + +namespace unicorn { + +//static std::once_flag gVMInitialization; +//static RuntimeVM* gRVM; +// +//RuntimeVM* RuntimeVM::ForProcess() { +// std::call_once(gVMInitialization, []() mutable { gRVM = new RuntimeVM(); }); +// +// return gRVM; +//} + + RuntimeVM::RuntimeVM() { + this->vm_ = RuntimeVM::CreateEngineVM(); + } + + RuntimeVM::~RuntimeVM() { + if (this->vm_) { + RuntimeVM::ReleaseEngineVM(this->vm_); + this->vm_ = nullptr; + } + } + + void *RuntimeVM::EngineVM() { return RuntimeVM::vm_; } + + bool RuntimeVM::Shutdown() { + RuntimeVM::ReleaseEngineVM(this->vm_); + this->vm_ = nullptr; + return true; + } + +// private + void RuntimeVM::Initialize() { + // TODO(zhangxiao): for vm initializing + } + +} // namespace unicorn diff --git a/weex_core/Source/js_runtime/runtime/runtime_vm.h b/weex_core/Source/js_runtime/runtime/runtime_vm.h new file mode 100644 index 0000000000..442a690e26 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/runtime_vm.h @@ -0,0 +1,70 @@ +/** + * 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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_RUNTIME_VM_H_ +#define FLUTTER_UNICORN_RUNTIME_RUNTIME_VM_H_ + +#include +#include + +namespace unicorn { +class EngineContext; +class RuntimeContext; + +class RuntimeVM { + public: + //static RuntimeVM* ForProcess(); + + RuntimeVM(); + ~RuntimeVM(); + + static void* CreateEngineVM(); + static void ReleaseEngineVM(void* vm); + + static EngineContext* GetEngineContext(const void* js_ctx); + static void NotifyContextCreated(RuntimeContext* context); + static void NotifyContextDestorying(RuntimeContext* context); + + void* EngineVM(); + bool Shutdown(); + + private: + void* vm_; + + void Initialize(); +}; + +} // namespace unicorn + +#endif // FLUTTER_UNICORN_RUNTIME_RUNTIME_VM_H_ diff --git a/weex_core/Source/js_runtime/runtime/v8/engine_context_v8.cc b/weex_core/Source/js_runtime/runtime/v8/engine_context_v8.cc new file mode 100644 index 0000000000..5fb7b3cc17 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/v8/engine_context_v8.cc @@ -0,0 +1,62 @@ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#include "js_runtime/runtime/v8/engine_context_v8.h" + +#include "js_runtime/runtime/runtime_controller.h" +#include "js_runtime/runtime/runtime_vm.h" + +namespace unicorn { + +EngineContextV8::EngineContextV8(EngineContextDelegate* delegate, RuntimeVM* vm) + : delegate_(delegate), vm_(vm) {} + +EngineContextV8::~EngineContextV8() { + JSGlobalContextRelease(context_); + + if (delegate_) delegate_->OnEngineContextFinalized(); + delegate_ = NULL; +} + +void EngineContextV8::InitializeContext() { + v8::Isolate* isolate = static_cast(vm_->EngineVM()); + v8::Isolate::Scope isolate_scope(isolate); + v8::HandleScope handle_scope(isolate); + Handle global = ObjectTemplate::New(); + auto context = Context::New(isolate, NULL, global); + context_.reset(isolate, context); +} + +void EngineContextV8::RunJavaScript(const std::string& script) {} + +void EngineContextV8::ThrowJSError(const std::string& error) {} + +void EngineContextV8::ThrowException(const std::string& error) {} + +void EngineContextV8::SetGlobalPropertyValue(const std::string& property_id, + ScopeValues value) { + +} + +ScopeValues EngineContextV8::GetGlobalProperty(std::string property_id) { + return RuntimeValues::MakeUndefined(); +} + +EngineContext* EngineContext::CreateEngineContext( + EngineContextDelegate* delegate, RuntimeVM* vm) { + return new EngineContextV8(delegate, vm); +} +} // namespace unicorn diff --git a/weex_core/Source/js_runtime/runtime/v8/engine_context_v8.h b/weex_core/Source/js_runtime/runtime/v8/engine_context_v8.h new file mode 100644 index 0000000000..51a656d076 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/v8/engine_context_v8.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. + */ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#ifndef FLUTTER_UNICORN_RUNTIME_V8_ENGINE_CONTEXT_V8_H_ +#define FLUTTER_UNICORN_RUNTIME_V8_ENGINE_CONTEXT_V8_H_ + +#include +#include +#include + +#include "js_runtime/runtime/engine_context.h" +#include "js_runtime/runtime/runtime_values.h" + +namespace unicorn { + +class RuntimeVM; + +class EngineContextV8 : public EngineContext { + public: + EngineContextV8(EngineContextDelegate* delegate, RuntimeVM* vm); + ~EngineContextV8(); + + void InitializeContext() override; + void RunJavaScript(const std::string& script) override; + void ThrowJSError(const std::string& error) override; + void ThrowException(const std::string& error) override; + void* GetContext() const override { return nullptr; } + void SetGlobalPropertyValue(const std::string& property_id, + ScopeValues value); + ScopeValues GetGlobalProperty(std::string property_id); + + private: + v8::Local get_context() { + v8::Isolate* isolate = static_cast(vm_->EngineVM()); + return context_.Get(isolate); + } + + EngineContextDelegate* delegate_; + RuntimeVM* vm_; + + v8::Persistent context_; +}; + +} // namespace unicorn + +#endif // FLUTTER_UNICORN_RUNTIME_V8_ENGINE_CONTEXT_V8_H_ diff --git a/weex_core/Source/js_runtime/runtime/v8/runtime_object_v8.cc b/weex_core/Source/js_runtime/runtime/v8/runtime_object_v8.cc new file mode 100644 index 0000000000..0b7e701684 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/v8/runtime_object_v8.cc @@ -0,0 +1,48 @@ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#include "js_runtime/runtime/runtime_object.h" + +#include "js_runtime/runtime/engine_context.h" + +namespace unicorn { + +bool RuntimeObject::HasProperty(std::string& name) { + return false; +} + +void RuntimeObject::SetProperty(std::string name&, void* class_ref, + RuntimeValues& value) { + if (value == nullptr || HasProperty(name)) + return; +} +void RuntimeObject::SetProperty(std::string& name, RuntimeObject* value) { + if (value == nullptr || HasProperty(name)) + return; + + RuntimeValues holder(static_cast(value)); + SetProperty(name, value->GetJSClass(), holder); +} + +RuntimeValues RuntimeObject::GetPropertyValue(std::string& name) { + return RuntimeValues(); +} + +bool RuntimeObject::DeleteProperty(std::string& name) { + return false; +} + +} // namespace unicorn diff --git a/weex_core/Source/js_runtime/runtime/v8/v8_base.h b/weex_core/Source/js_runtime/runtime/v8/v8_base.h new file mode 100644 index 0000000000..a75a6f9680 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/v8/v8_base.h @@ -0,0 +1,24 @@ +/** + * 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 FLUTTER_UNICORN_RUNTIME_JSC_V8_BASE_H_ +#define FLUTTER_UNICORN_RUNTIME_JSC_V8_BASE_H_ + +#include + +#endif // FLUTTER_UNICORN_RUNTIME_JSC_V8_BASE_H_ diff --git a/weex_core/Source/js_runtime/runtime/v8/vm_v8.cc b/weex_core/Source/js_runtime/runtime/v8/vm_v8.cc new file mode 100644 index 0000000000..36bfd05614 --- /dev/null +++ b/weex_core/Source/js_runtime/runtime/v8/vm_v8.cc @@ -0,0 +1,36 @@ +/** +# Copyright 2018 Taobao (China) Inc. +# +# 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. +**/ + +#include +#include "js_runtime/runtime/runtime_vm.h" + +namespace unicorn { + +// implemete engine vm create function +void* RuntimeVM::CreateEngineVM() { + // initialize jsc threading environment + // create vm + v8::Isolate* isolate = v8::Isolate::New(); + return static_cast(isolate); +} + +void RuntimeVM::ReleaseEngineVM(void* vm) { + if (vm == nullptr) return; + v8::Isolate* isolate = static_cast(vm); + isolate->Dispose(); +} + +} // namespace unicorn diff --git a/weex_core/Source/js_runtime/utils/base64.hpp b/weex_core/Source/js_runtime/utils/base64.hpp new file mode 100644 index 0000000000..21db57ba6a --- /dev/null +++ b/weex_core/Source/js_runtime/utils/base64.hpp @@ -0,0 +1,253 @@ +// +// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +/* + Portions from http://www.adp-gmbh.ch/cpp/common/base64.html + Copyright notice: + + base64.cpp and base64.h + + Copyright (C) 2004-2008 Ren� Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + Ren� Nyffenegger rene.nyffenegger@adp-gmbh.ch + +*/ + +/** + * boost source + * url : https://raw.githubusercontent.com/boostorg/beast/3777cb8b9c78748d0e64401316f00382d37b83be/include/beast/core/detail/base64.hpp + */ + + +#ifndef BEAST_DETAIL_BASE64_HPP +#define BEAST_DETAIL_BASE64_HPP + +#include +#include +#include + +namespace beast { +namespace detail { + +namespace base64 { + +inline +char const* +get_alphabet() +{ + static char constexpr tab[] = { + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + }; + return &tab[0]; +} + +inline +signed char const* +get_inverse() +{ + static signed char constexpr tab[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0-15 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32-47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48-63 + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79 + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80-95 + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111 + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112-127 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128-143 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144-159 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-175 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176-191 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192-207 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208-223 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 240-255 + }; + return &tab[0]; +} + + +/// Returns max chars needed to encode a base64 string +inline +std::size_t constexpr +encoded_size(std::size_t n) +{ + return 4 * ((n + 2) / 3); +} + +/// Returns max bytes needed to decode a base64 string +inline +std::size_t constexpr +decoded_size(std::size_t n) +{ + return n / 4 * 3; // requires n&3==0, smaller + //return 3 * n / 4; +} + +/** Encode a series of octets as a padded, base64 string. + + The resulting string will not be null terminated. + + @par Requires + + The memory pointed to by `out` points to valid memory + of at least `encoded_size(len)` bytes. + + @return The number of characters written to `out`. This + will exclude any null termination. +*/ +template +std::size_t +encode(void* dest, void const* src, std::size_t len) +{ + char* out = static_cast(dest); + char const* in = static_cast(src); + auto const tab = base64::get_alphabet(); + + for(auto n = len / 3; n--;) + { + *out++ = tab[ (in[0] & 0xfc) >> 2]; + *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)]; + *out++ = tab[((in[2] & 0xc0) >> 6) + ((in[1] & 0x0f) << 2)]; + *out++ = tab[ in[2] & 0x3f]; + in += 3; + } + + switch(len % 3) + { + case 2: + *out++ = tab[ (in[0] & 0xfc) >> 2]; + *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)]; + *out++ = tab[ (in[1] & 0x0f) << 2]; + *out++ = '='; + break; + + case 1: + *out++ = tab[ (in[0] & 0xfc) >> 2]; + *out++ = tab[((in[0] & 0x03) << 4)]; + *out++ = '='; + *out++ = '='; + break; + + case 0: + break; + } + + return out - static_cast(dest); +} + +/** Decode a padded base64 string into a series of octets. + + @par Requires + + The memory pointed to by `out` points to valid memory + of at least `decoded_size(len)` bytes. + + @return The number of octets written to `out`, and + the number of characters read from the input string, + expressed as a pair. +*/ +template +std::pair +decode(void* dest, char const* src, std::size_t len) +{ + char* out = static_cast(dest); + auto in = reinterpret_cast(src); + unsigned char c3[3], c4[4]; + int i = 0; + int j = 0; + + auto const inverse = base64::get_inverse(); + + while(len-- && *in != '=') + { + auto const v = inverse[*in]; + if(v == -1) + break; + ++in; + c4[i] = v; + if(++i == 4) + { + c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4); + c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2); + c3[2] = ((c4[2] & 0x3) << 6) + c4[3]; + + for(i = 0; i < 3; i++) + *out++ = c3[i]; + i = 0; + } + } + + if(i) + { + c3[0] = ( c4[0] << 2) + ((c4[1] & 0x30) >> 4); + c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2); + c3[2] = ((c4[2] & 0x3) << 6) + c4[3]; + + for(j = 0; j < i - 1; j++) + *out++ = c3[j]; + } + + return {out - static_cast(dest), + in - reinterpret_cast(src)}; +} + +} // base64 + +template +std::string +base64_encode (std::uint8_t const* data, + std::size_t len) +{ + std::string dest; + dest.resize(base64::encoded_size(len)); + dest.resize(base64::encode(&dest[0], data, len)); + return dest; +} + +inline +std::string +base64_encode(std::string const& s) +{ + return base64_encode (reinterpret_cast < + std::uint8_t const*> (s.data()), s.size()); +} + +template +std::string +base64_decode(std::string const& data) +{ + std::string dest; + dest.resize(base64::decoded_size(data.size())); + auto const result = base64::decode( + &dest[0], data.data(), data.size()); + dest.resize(result.first); + return dest; +} + +} // detail +} // beast + +#endif \ No newline at end of file diff --git a/weex_core/Source/js_runtime/utils/log_utils.h b/weex_core/Source/js_runtime/utils/log_utils.h new file mode 100644 index 0000000000..a75e7d16d1 --- /dev/null +++ b/weex_core/Source/js_runtime/utils/log_utils.h @@ -0,0 +1,62 @@ +/** + * 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 陈佩翰 on 2019/1/17. +// + +#ifndef WEEXCORE_LOG_UTILS_H +#define WEEXCORE_LOG_UTILS_H + +#include "base/utils/log_utils.h" + +#ifdef LOG_JS_RUNTIME_DEBUG +#define LOG_JS_RUNTIME(...) __android_log_print(ANDROID_LOG_WARN,"[JS_RUNTIME]", __VA_ARGS__) +#else +#define LOG_JS_RUNTIME(...) ((void)0) +#endif + + +#ifdef LOG_WEEX_RUNTIME_DEBUG +#define LOG_RUNTIME(...) __android_log_print(ANDROID_LOG_WARN,"[WEEX_RUNTIME]", __VA_ARGS__) +#else +#define LOG_RUNTIME(...) ((void)0) +#endif + +#ifdef LOG_CONVERSION_DEBUG +#define LOG_CONVERSION(...) __android_log_print(ANDROID_LOG_DEBUG,"[CONVERSION]", __VA_ARGS__) +#else +#define LOG_CONVERSION(...) ((void)0) +#endif + +#ifdef LOG_WEEX_BINDING_DEBUG +#define LOG_WEEX_BINDING(...) __android_log_print(ANDROID_LOG_WARN,"[WEEX_BINDING]", __VA_ARGS__) +#else +#define LOG_WEEX_BINDING(...) ((void)0) +#endif + +#ifdef LOG_JS_DEBUG +#define LOG_JS(...) LOGI(__VA_ARGS__) +#else +#define LOG_JS(...) ((void)0) +#endif + +#define LOG_JS_ERROR(...) LOGE(__VA_ARGS__) + + +#endif //WEEXCORE_LOG_UTILS_H diff --git a/weex_core/Source/js_runtime/weex/binding/app_context_binding.cpp b/weex_core/Source/js_runtime/weex/binding/app_context_binding.cpp new file mode 100644 index 0000000000..c15ab25856 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/binding/app_context_binding.cpp @@ -0,0 +1,202 @@ +/** + * 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 陈佩翰 on 2019/1/23. +// + + +#include "app_context_binding.h" +#include "weex_binding_utils.h" +#include "core/bridge/script_bridge.h" +#include "js_runtime/weex/object/weex_global_object_v2.h" +#include "js_runtime/weex/utils/weex_conversion_utils.h" + +namespace weex { + namespace jsengine { + CLASS_METHOD_CALLBACK(AppWorkerBinding, nativeLog) + + CLASS_METHOD_CALLBACK(AppWorkerBinding, __dispatch_message__) + + CLASS_METHOD_CALLBACK(AppWorkerBinding, __dispatch_message_sync__) + + CLASS_METHOD_CALLBACK(AppWorkerBinding, postMessage) + + CLASS_METHOD_CALLBACK(AppWorkerBinding, setNativeTimeout) + + CLASS_METHOD_CALLBACK(AppWorkerBinding, setNativeInterval) + + CLASS_METHOD_CALLBACK(AppWorkerBinding, clearNativeTimeout) + + CLASS_METHOD_CALLBACK(AppWorkerBinding, clearNativeInterval) + + CLASS_MEMBER_GET_CALLBACK(AppWorkerBinding, console) + + CLASS_REGISTER_START(AppWorkerBinding, AppWorker) + SET_IS_GLOBAL + REGISTER_METHOD_CALLBACK(AppWorkerBinding, nativeLog) + REGISTER_METHOD_CALLBACK(AppWorkerBinding, __dispatch_message__) + REGISTER_METHOD_CALLBACK(AppWorkerBinding, __dispatch_message_sync__) + REGISTER_METHOD_CALLBACK(AppWorkerBinding, postMessage) + REGISTER_METHOD_CALLBACK(AppWorkerBinding, setNativeTimeout) + REGISTER_METHOD_CALLBACK(AppWorkerBinding, setNativeInterval) + REGISTER_METHOD_CALLBACK(AppWorkerBinding, clearNativeTimeout) + REGISTER_METHOD_CALLBACK(AppWorkerBinding, clearNativeInterval) + REGISTER_GET_CALLBACK(AppWorkerBinding, console) + CLASS_REGISTER_END(AppWorkerBinding) + + AppWorkerBinding::AppWorkerBinding(unicorn::EngineContext *context, const OpaqueJSContext *js_ctx) + : RuntimeObject(context, js_ctx) { + // SetJSClass(AppWorkerBinding::s_jsclass_AppWorkerBinding); + consoleBinding.reset(new WeexConsoleBinding(context, js_ctx)); + SetJSClass(AppWorkerBinding::CreateClassRef(context)); + } + + AppWorkerBinding::~AppWorkerBinding() { + this->nativeObject = nullptr; + } + + unicorn::ScopeValues + AppWorkerBinding::nativeLog(const std::vector &vars) { + return WeexBindingUtils::nativeLog(this->nativeObject, vars, false); + } + + unicorn::ScopeValues AppWorkerBinding::__dispatch_message__( + const std::vector &vars) { + + LOG_WEEX_BINDING("WeexRuntime: __dispatch_message__"); + if (nullptr == this->nativeObject){ + return unicorn::RuntimeValues::MakeInt(0); + } + + std::string client_id; + std::string data; + std::string callback; + std::string vm_id; + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, client_id); + LOG_WEEX_BINDING("WeexRuntime: __dispatch_message__ client_id is %s", client_id.c_str()); + + WeexConversionUtils::GetJSONArgsFromArgsByWml(vars, 1, data); + //bool succeed = WeexConversionUtils::GetJSONArgsFromArgsByWml(vars, 1, data); + //const char *data_char = succeed ? data.c_str() : nullptr; + LOG_WEEX_BINDING("WeexRuntime: __dispatch_message__ data is %s", data.c_str()); + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 2, callback); + LOG_WEEX_BINDING("WeexRuntime: __dispatch_message__ callback is %s", callback.c_str()); + + vm_id = this->nativeObject->id; + LOG_WEEX_BINDING("WeexRuntime: __dispatch_message__ vm_id is %s", vm_id.c_str()); + + this->nativeObject->js_bridge()->core_side()->DispatchMessage(client_id.c_str(), data.c_str(), data.length(), + callback.c_str(), vm_id.c_str()); + return unicorn::RuntimeValues::MakeInt(0); + } + + unicorn::ScopeValues + AppWorkerBinding::__dispatch_message_sync__( + const std::vector &vars) { + LOG_WEEX_BINDING("WeexRuntime: __dispatch_message_sync__"); + if (nullptr == this->nativeObject){ + return unicorn::RuntimeValues::MakeUndefined(); + } + + std::string client_id; + std::string data; + std::string vm_id; + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, client_id); + WeexConversionUtils::GetJSONArgsFromArgsByWml(vars, 1, data); + vm_id = this->nativeObject->id; + + LOG_WEEX_BINDING("WeexRuntime: __dispatch_message__ , cliend:%s, vm:%s,data:%s", client_id.c_str(), + vm_id.c_str(), data.c_str()); + + auto result = this->nativeObject->js_bridge()->core_side()->DispatchMessageSync(client_id.c_str(), + data.c_str(), + data.length(), + vm_id.c_str()); + + LOG_WEEX_BINDING("WeexRuntime: __dispatch_message__ , result:%s", result->data.get()); + + if (result->length == 0) { + return unicorn::RuntimeValues::MakeUndefined(); + } else { + return unicorn::RuntimeValues::MakeObjectFromJsonStr(result->data.get()); + } + + } + + unicorn::ScopeValues + AppWorkerBinding::postMessage(const std::vector &vars) { + LOG_WEEX_BINDING("WeexRuntime: postMessage"); + if (nullptr == this->nativeObject){ + return unicorn::RuntimeValues::MakeInt(0); + } + + std::string data; + std::string vm_id; + + + WeexConversionUtils::GetJSONArgsFromArgsByWml(vars, 0, data); + // const char *data_char = succeed ? data.c_str() : nullptr; + //LOG_WEEX_BINDING("WeexRuntime: postMessage data is %s", data_char); + + + vm_id = this->nativeObject->id; + //LOG_WEEX_BINDING("WeexRuntime: __dispatch_message__ vm_id is %s", vm_id.c_str()); + + this->nativeObject->js_bridge()->core_side()->PostMessage(vm_id.c_str(), data.c_str(), data.length()); + + return unicorn::RuntimeValues::MakeInt(0); + } + + unicorn::ScopeValues + AppWorkerBinding::setNativeTimeout(std::vector &vars) { + LOG_WEEX_BINDING("appConteext: setNativeTimeout this:%p,nativeObject:%p", this, nativeObject); + return WeexBindingUtils::setNativeTimeout(this->nativeObject, vars, false); + } + + unicorn::ScopeValues AppWorkerBinding::setNativeInterval( + std::vector &vars) { + LOG_WEEX_BINDING("appConteext: setNativeInterval this:%p,nativeObject:%p", this, nativeObject); + return WeexBindingUtils::setNativeTimeout(this->nativeObject, vars, true); + } + + unicorn::ScopeValues AppWorkerBinding::clearNativeTimeout( + std::vector &vars) { + return WeexBindingUtils::clearNativeTimeout(this->nativeObject, vars); + } + + unicorn::ScopeValues AppWorkerBinding::clearNativeInterval( + std::vector &vars) { + return WeexBindingUtils::clearNativeTimeout(this->nativeObject, vars); + } + + unicorn::ScopeValues + AppWorkerBinding::console() { + if(nullptr == nativeObject || nullptr == this->consoleBinding.get()){ + return unicorn::RuntimeValues::MakeUndefined(); + } + return unicorn::RuntimeValues::MakeCommonObject( + static_cast(this->consoleBinding.get()), + new unicorn::RuntimeClass(consoleBinding->GetJSClass()) + ); + } + } +} diff --git a/weex_core/Source/js_runtime/weex/binding/app_context_binding.h b/weex_core/Source/js_runtime/weex/binding/app_context_binding.h new file mode 100644 index 0000000000..2b33787c3f --- /dev/null +++ b/weex_core/Source/js_runtime/weex/binding/app_context_binding.h @@ -0,0 +1,74 @@ +/** + * 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 陈佩翰 on 2019/1/23. +// + +#ifndef PROJECT_APP_INSTANCE_BINDING_H +#define PROJECT_APP_INSTANCE_BINDING_H + +#include "js_runtime/runtime/binding_macro.h" +#include "weex_console_binding.h" + +class WeexGlobalObjectV2; + +namespace weex { + namespace jsengine { + class AppWorkerBinding : public unicorn::RuntimeObject { + public: + DECLARE_CLASS_REGISTER_OP(AppWorkerBinding) + + AppWorkerBinding(unicorn::EngineContext *context, const OpaqueJSContext *js_ctx); + + ~AppWorkerBinding() override; + + unicorn::ScopeValues nativeLog(const std::vector &vars); + + unicorn::ScopeValues + __dispatch_message__(const std::vector &vars); + + unicorn::ScopeValues + __dispatch_message_sync__(const std::vector &vars); + + unicorn::ScopeValues + postMessage(const std::vector &vars); + + unicorn::ScopeValues + setNativeTimeout(std::vector &vars); + + unicorn::ScopeValues + setNativeInterval(std::vector &vars); + + unicorn::ScopeValues + clearNativeTimeout(std::vector &vars); + + unicorn::ScopeValues + clearNativeInterval(std::vector &vars); + + unicorn::ScopeValues console(); + + public: + WeexGlobalObjectV2* nativeObject = nullptr; + std::unique_ptr consoleBinding; + }; + } +} + + +#endif //PROJECT_APP_INSTANCE_BINDING_H diff --git a/weex_core/Source/js_runtime/weex/binding/weex_binding_utils.cpp b/weex_core/Source/js_runtime/weex/binding/weex_binding_utils.cpp new file mode 100644 index 0000000000..e5ec1cf1f0 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/binding/weex_binding_utils.cpp @@ -0,0 +1,198 @@ +/** + * 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 陈佩翰 on 2019/2/12. +// + +#include +#include "weex_binding_utils.h" +#include "js_runtime/utils/log_utils.h" +#include "core/bridge/script_bridge.h" +#include "js_runtime/weex/object/weex_global_object_v2.h" +#include "js_runtime/utils/base64.hpp" + +namespace weex { + namespace jsengine { + unicorn::ScopeValues + WeexBindingUtils::atob(WeexGlobalObjectV2 *nativeObject, + const std::vector &vars) { + if (vars.size() > 0 && vars[0]->IsString()) { + std::string origin_data; + vars[0]->GetAsString(&origin_data); + std::string res = beast::detail::base64_decode(origin_data); + return unicorn::RuntimeValues::MakeString(res); + } else { + return unicorn::RuntimeValues::MakeUndefined(); + } + + } + + unicorn::ScopeValues + WeexBindingUtils::btoa(WeexGlobalObjectV2 *nativeObject, + const std::vector &vars) { + std::string origin_data; + + if (vars.size() > 0 && vars[0]->IsString()) { + vars[0]->GetAsString(&origin_data); + } else { + origin_data = ""; + } + std::string res = beast::detail::base64_encode(origin_data); + return unicorn::RuntimeValues::MakeString(res); + } + + unicorn::ScopeValues WeexBindingUtils::nativeLog(WeexGlobalObjectV2 *nativeObject, + const std::vector &vars, + bool toCoreSide) { + // LOG_JS("[JS] enter native log :args->size %d", vars.size()); + if (vars.empty()) { + unicorn::RuntimeValues::MakeBool(true); + } + std::string logStr; + for (int i = 0; i < vars.size(); i++) { + std::string logItem; + WeexConversionUtils::GetStringFromArgsDefaultUndefined(vars, i, logItem); + vars[i]->GetAsString(&logItem); + logStr.append(logItem); + } + + // LOG_JS("[WeexBindingUtils][JS] %s", logStr.c_str()); + if (toCoreSide && !logStr.empty()) { + nativeObject->js_bridge()->core_side()->NativeLog(logStr.c_str()); + } + return unicorn::RuntimeValues::MakeUndefined(); + } + + unicorn::ScopeValues WeexBindingUtils::setNativeTimeout(WeexGlobalObjectV2 *nativeObject, + std::vector &vars, + bool interval) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeInt(0); + } + if (vars.size() < 2 || !vars[0]->IsFunction() || !vars[1]->IsNumber()) { + if (vars.size() < 2) { + LOG_WEEX_BINDING("WeexBindingUtils method :setNativeTimeout argsSize check failed, argSize:%d", + vars.size()); + } else { + LOG_WEEX_BINDING( + "WeexBindingUtils method :setNativeTimeout argsType check failed, 1type::%d,2type:%d", + vars[0]->GetType(), vars[1]->GetType()); + } + return unicorn::RuntimeValues::MakeInt(0); + } + unicorn::RuntimeValues *func = vars[0].release(); + int timeout; + vars[1]->GetAsInteger(&timeout); + int task_id = nativeObject->setNativeTimeout(func, timeout, interval); + return unicorn::RuntimeValues::MakeInt(task_id); + } + + + unicorn::ScopeValues + WeexBindingUtils::clearNativeTimeout(WeexGlobalObjectV2 *nativeObject, + std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeInt(0); + } + if (vars.size() > 0 && vars[0]->IsNumber()) { + int timerId; + vars[0]->GetAsInteger(&timerId); + nativeObject->clearNativeTimeout(timerId); + } + return unicorn::RuntimeValues::MakeInt(0); + } + + unicorn::ScopeValues + WeexBindingUtils::callT3DLinkNative(WeexGlobalObjectV2 *nativeObject, + const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeString(std::string("")); + } + + + int type; + std::string arg_str; + + vars[0]->GetAsInteger(&type); + WeexConversionUtils::GetStringFromArgsDefaultUndefined(vars, 1, arg_str); + + LOG_WEEX_BINDING("WeexBindingUtils method :callT3DLinkNative type:%d, arg_str:%s", type, arg_str.c_str()); + + auto result = nativeObject->js_bridge()->core_side()->CallT3DLinkNative(type, arg_str.c_str()); + std::string result_str = std::string(nullptr == result? "":result); + return unicorn::RuntimeValues::MakeString(result_str); + } + + unicorn::ScopeValues + WeexBindingUtils::callGCanvasLinkNative(WeexGlobalObjectV2 *nativeObject, + const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeString(std::string("")); + } + + std::string id_str; + int type; + std::string arg_str; + + WeexConversionUtils::GetStringFromArgsDefaultUndefined(vars, 0, id_str); + vars[1]->GetAsInteger(&type); + WeexConversionUtils::GetStringFromArgsDefaultUndefined(vars, 2, arg_str); + + LOG_WEEX_BINDING("WeexBindingUtils callGCanvasLinkNative id:%s,type:%d,arg:%s", + id_str.c_str(), + type, + arg_str.c_str() + ); + + auto result = nativeObject->js_bridge()->core_side()->CallGCanvasLinkNative( + id_str.c_str(), type, arg_str.c_str() + ); + + if (nullptr == result) { + return unicorn::RuntimeValues::MakeString(std::string("")); + } else { + return unicorn::RuntimeValues::MakeString(std::string(result)); + } + } + + unicorn::ScopeValues + WeexBindingUtils::__updateComponentData(WeexGlobalObjectV2 *nativeObject, + const std::vector &vars) { + + std::string page_id; + std::string cid; + std::string json_data; + + WeexConversionUtils::GetStringFromArgsDefaultUndefined(vars, 0, page_id); + WeexConversionUtils::GetStringFromArgsDefaultUndefined(vars, 1, cid); + bool succeed = WeexConversionUtils::GetCharOrJsonFromArgs(vars, 2, json_data); + const char *json_data_char = succeed ? json_data.c_str() : nullptr; + + LOG_WEEX_BINDING("WeexGlobalBinding method :__updateComponentData page:%s, cid:%s,json_data:%s", + page_id.c_str(), cid.c_str(), json_data_char + ); + + nativeObject->js_bridge()->core_side()->UpdateComponentData(page_id.c_str(), cid.c_str(), + json_data_char); + return unicorn::RuntimeValues::MakeUndefined(); + } + + + } +} diff --git a/weex_core/Source/js_runtime/weex/binding/weex_binding_utils.h b/weex_core/Source/js_runtime/weex/binding/weex_binding_utils.h new file mode 100644 index 0000000000..26aa2e6722 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/binding/weex_binding_utils.h @@ -0,0 +1,65 @@ +/** + * 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 陈佩翰 on 2019/2/12. +// + +#ifndef PROJECT_WEEX_BINDING_UTILS_H +#define PROJECT_WEEX_BINDING_UTILS_H + +#include + +class WeexGlobalObjectV2; + +namespace weex { + namespace jsengine { + class WeexBindingUtils { + public: + static unicorn::ScopeValues + atob(WeexGlobalObjectV2 *nativeObject, const std::vector &vars); + + static unicorn::ScopeValues + btoa(WeexGlobalObjectV2 *nativeObject, const std::vector &vars); + + static unicorn::ScopeValues + nativeLog(WeexGlobalObjectV2 *nativeObject, const std::vector &vars, bool toCoreSide); + + static unicorn::ScopeValues + setNativeTimeout(WeexGlobalObjectV2 *nativeObject, std::vector &vars, bool interval); + + static unicorn::ScopeValues + clearNativeTimeout(WeexGlobalObjectV2 *nativeObject, std::vector &vars); + + static unicorn::ScopeValues + callT3DLinkNative(WeexGlobalObjectV2 *nativeObject, const std::vector &vars); + + + static unicorn::ScopeValues + callGCanvasLinkNative(WeexGlobalObjectV2 *nativeObject, const std::vector &vars); + + + static unicorn::ScopeValues + __updateComponentData(WeexGlobalObjectV2 *nativeObject, const std::vector &vars); + + }; + } +} + + +#endif //PROJECT_WEEX_BINDING_UTILS_H diff --git a/weex_core/Source/js_runtime/weex/binding/weex_console_binding.cpp b/weex_core/Source/js_runtime/weex/binding/weex_console_binding.cpp new file mode 100644 index 0000000000..a85403545f --- /dev/null +++ b/weex_core/Source/js_runtime/weex/binding/weex_console_binding.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. + */ +// +// Created by 陈佩翰 on 2019/3/4. +// + +#include "weex_console_binding.h" + +namespace weex { + namespace jsengine { + + + CLASS_METHOD_CALLBACK(WeexConsoleBinding, log) + + CLASS_METHOD_CALLBACK(WeexConsoleBinding, info) + + CLASS_METHOD_CALLBACK(WeexConsoleBinding, debug) + + CLASS_METHOD_CALLBACK(WeexConsoleBinding, warn) + + CLASS_METHOD_CALLBACK(WeexConsoleBinding, error) + + CLASS_REGISTER_START(WeexConsoleBinding, console) + REGISTER_METHOD_CALLBACK(WeexConsoleBinding, log) + REGISTER_METHOD_CALLBACK(WeexConsoleBinding, info) + REGISTER_METHOD_CALLBACK(WeexConsoleBinding, debug) + REGISTER_METHOD_CALLBACK(WeexConsoleBinding, warn) + REGISTER_METHOD_CALLBACK(WeexConsoleBinding, error) + CLASS_REGISTER_END(WeexConsoleBinding) + + + WeexConsoleBinding::WeexConsoleBinding(unicorn::EngineContext *context, const OpaqueJSContext *js_ctx) + : RuntimeObject(context, js_ctx) { + SetJSClass(WeexConsoleBinding::CreateClassRef(context)); + } + +// enum class MessageLevel { +// Log = 1, +// Warning = 2, +// Error = 3, +// Debug = 4, +// Info = 5, +// }; + + + unicorn::ScopeValues WeexConsoleBinding::info(std::vector &vars) { + return printLog(5, vars); + } + + unicorn::ScopeValues WeexConsoleBinding::debug(std::vector &vars) { + return printLog(4, vars); + } + + unicorn::ScopeValues WeexConsoleBinding::warn(std::vector &vars) { + return printLog(2, vars); + } + + unicorn::ScopeValues WeexConsoleBinding::error(std::vector &vars) { + return printLog(3, vars); + } + + unicorn::ScopeValues WeexConsoleBinding::log(std::vector &vars) { + return printLog(1, vars); + } + + unicorn::ScopeValues WeexConsoleBinding::printLog(int level, std::vector &vars) { + + if (vars.size() < 1 || !vars[0]->IsString()) { + return unicorn::RuntimeValues::MakeUndefined(); + } + std::string log; + vars[0]->GetAsString(&log); + Weex::LogUtil::ConsoleLogPrint(level, "jsLog", log.c_str()); + return unicorn::RuntimeValues::MakeUndefined(); + } + } +} + diff --git a/weex_core/Source/js_runtime/weex/binding/weex_console_binding.h b/weex_core/Source/js_runtime/weex/binding/weex_console_binding.h new file mode 100644 index 0000000000..4012e69458 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/binding/weex_console_binding.h @@ -0,0 +1,57 @@ +/** + * 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 陈佩翰 on 2019/3/4. +// + +#ifndef PROJECT_WEEX_CONSOLE_BINDING_H +#define PROJECT_WEEX_CONSOLE_BINDING_H + +#include "js_runtime/runtime/runtime_object.h" +#include "js_runtime/runtime/binding_macro.h" + +namespace weex { + namespace jsengine { + class WeexConsoleBinding : public unicorn::RuntimeObject { + + public: + DECLARE_CLASS_REGISTER_OP(WeexConsoleBinding) + + WeexConsoleBinding(unicorn::EngineContext *context, const OpaqueJSContext *js_ctx); + + unicorn::ScopeValues log(std::vector &vars); + + unicorn::ScopeValues info(std::vector &vars); + + + unicorn::ScopeValues debug(std::vector &vars); + + unicorn::ScopeValues warn(std::vector &vars); + + unicorn::ScopeValues error(std::vector &vars); + + private: + unicorn::ScopeValues printLog(int level, std::vector &vars); + + }; + } +} + + +#endif //PROJECT_WEEX_CONSOLE_BINDING_H diff --git a/weex_core/Source/js_runtime/weex/binding/weex_global_binding.cpp b/weex_core/Source/js_runtime/weex/binding/weex_global_binding.cpp new file mode 100644 index 0000000000..5bf291bffd --- /dev/null +++ b/weex_core/Source/js_runtime/weex/binding/weex_global_binding.cpp @@ -0,0 +1,592 @@ +/** + * 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 陈佩翰 on 2019/1/23. +// + +#include "weex_global_binding.h" +#include "js_runtime/utils/log_utils.h" +#include "weex_binding_utils.h" +#include "core/bridge/script_bridge.h" +#include "js_runtime/weex/utils/weex_conversion_utils.h" +#include +#include "js_runtime/weex/object/weex_global_object_v2.h" + +namespace weex { + namespace jsengine { + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callNative) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callNativeModule) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callNativeComponent) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, setTimeoutNative) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, nativeLog) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, notifyTrimMemory) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, markupState) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, atob) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, btoa) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callCreateBody) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callUpdateFinish) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callCreateFinish) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callRefreshFinish) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callUpdateAttrs) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callUpdateStyle) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callAddElement) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callRemoveElement) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callMoveElement) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callAddEvent) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callRemoveEvent) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callGCanvasLinkNative) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, setIntervalWeex) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, clearIntervalWeex) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, callT3DLinkNative) + + CLASS_METHOD_CALLBACK(WeexGlobalBinding, __updateComponentData) + + CLASS_REGISTER_START(WeexGlobalBinding, Global) + SET_IS_GLOBAL + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callNative) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callNativeModule) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callNativeComponent) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, setTimeoutNative) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, nativeLog) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, notifyTrimMemory) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, markupState) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, atob) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, btoa) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callCreateBody) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callUpdateFinish) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callCreateFinish) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callRefreshFinish) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callUpdateAttrs) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callUpdateStyle) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callAddElement) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callRemoveElement) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callMoveElement) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callAddEvent) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callRemoveEvent) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callGCanvasLinkNative) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, setIntervalWeex) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, clearIntervalWeex) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, callT3DLinkNative) + REGISTER_METHOD_CALLBACK(WeexGlobalBinding, __updateComponentData) + CLASS_REGISTER_END(WeexGlobalBinding) + + + WeexGlobalBinding::~WeexGlobalBinding() { + LOG_WEEX_BINDING("WeexGlobalBinding delete"); + this->nativeObject = nullptr; + } + + WeexGlobalBinding::WeexGlobalBinding(unicorn::EngineContext *context, const OpaqueJSContext *js_ctx) + : RuntimeObject(context, js_ctx) { + //SetJSClass(WeexGlobalBinding::s_jsclass_WeexGlobalBinding); + SetJSClass(WeexGlobalBinding::CreateClassRef(context)); + LOG_WEEX_BINDING("WeexGlobalBinding init"); + } + + unicorn::ScopeValues + WeexGlobalBinding::setIntervalWeex(const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + std::string page_id; + std::string task_str; + std::string callback_str; + + WeexConversionUtils::GetStringFromArgsDefaultUndefined(vars, 0, page_id); + WeexConversionUtils::GetStringFromArgsDefaultUndefined(vars, 1, task_str); + WeexConversionUtils::GetStringFromArgsDefaultUndefined(vars, 2, callback_str); + + LOG_WEEX_BINDING("WeexGlobalBinding method :setIntervalWeex page:% , task:%s , callback:%s", + page_id.c_str(), task_str.c_str(), callback_str.c_str()); + + int result = nativeObject->js_bridge()->core_side()->SetInterval(page_id.c_str(), task_str.c_str(), + callback_str.c_str()); + return unicorn::RuntimeValues::MakeInt(result); + } + + unicorn::ScopeValues WeexGlobalBinding::clearIntervalWeex( + const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeBool(false); + } + + std::string page_id; + std::string callback_str; + + WeexConversionUtils::GetStringFromArgsDefaultUndefined(vars, 0, page_id); + WeexConversionUtils::GetStringFromArgsDefaultUndefined(vars, 1, callback_str); + + LOG_WEEX_BINDING("WeexGlobalBinding method :clearIntervalWeex page:%s, callBacK :%s", page_id.c_str(), + callback_str.c_str()); + + nativeObject->js_bridge()->core_side()->ClearInterval(page_id.c_str(), callback_str.c_str()); + + return unicorn::RuntimeValues::MakeBool(true); + } + + + unicorn::ScopeValues + WeexGlobalBinding::callNative(const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + std::string page_id; + std::string task; + std::string callback_str; + + WeexConversionUtils::GetStringFromArgsDefaultUndefined(vars, 0, page_id); + bool succeed = WeexConversionUtils::GetCharOrJsonFromArgs(vars, 1, task); + const char *task_char = succeed ? task.c_str() : nullptr; + WeexConversionUtils::GetStringFromArgsDefaultUndefined(vars, 2, callback_str); + + LOG_WEEX_BINDING("WeexGlobalBinding callNative id_js:%s,task_str:%s,callback_str:%s", + page_id.c_str(), task_char, callback_str.c_str()); + + this->nativeObject->js_bridge()->core_side()->CallNative(page_id.c_str(), task_char, + callback_str.c_str()); + return unicorn::RuntimeValues::MakeUndefined(); + } + + unicorn::ScopeValues WeexGlobalBinding::callGCanvasLinkNative( + const std::vector &vars) { + LOG_WEEX_BINDING("WeexGlobalBinding method :callGCanvasLinkNative"); + return WeexBindingUtils::callGCanvasLinkNative(nativeObject, vars); + } + + + unicorn::ScopeValues WeexGlobalBinding::callT3DLinkNative(const std::vector &vars) { + LOG_WEEX_BINDING("WeexGlobalBinding method :callT3DLinkNative"); + return WeexBindingUtils::callT3DLinkNative(nativeObject, vars); + } + + unicorn::ScopeValues WeexGlobalBinding::callNativeModule(const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + std::string instanceId; + std::string module; + std::string method; + Args argument; + Args options; + + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, instanceId); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 1, module); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 2, method); + + LOG_WEEX_BINDING("WeexRuntime: callNativeModule %s %s", module.c_str(), method.c_str()); + + WeexConversionUtils::GetWsonFromArgs(vars, 3, argument); + WeexConversionUtils::GetWsonFromArgs(vars, 4, options); + + + auto result = this->nativeObject->js_bridge()->core_side()->CallNativeModule( + instanceId.c_str(), + module.c_str(), + method.c_str(), + argument.getValue(), + argument.getLength(), + options.getValue(), + options.getLength() + ); + auto ret = WeexConversionUtils::WeexValueToRuntimeValue(GetEngineContext(), result.get()); +// LOG_WEEX_BINDING("end :callNativeModule instance:%s,module:%s,method:%s", +// instanceId.c_str(), module.c_str(), method.c_str()); +// return ret; + return ret; + } + + unicorn::ScopeValues WeexGlobalBinding::callNativeComponent( + const std::vector &vars) { + + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + std::string instanceId; + std::string module; + std::string method; + Args argument; + Args options; + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, instanceId); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 1, module); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 2, method); + + LOG_WEEX_BINDING("WeexRuntime: callNativeComponent %s %s", module.c_str(), method.c_str()); + + WeexConversionUtils::GetWsonFromArgs(vars, 3, argument); + WeexConversionUtils::GetWsonFromArgs(vars, 4, options); + + this->nativeObject->js_bridge()->core_side()->CallNativeComponent( + instanceId.c_str(), + module.c_str(), + method.c_str(), + argument.getValue(), + argument.getLength(), + options.getValue(), + options.getLength() + ); + return unicorn::RuntimeValues::MakeInt(0); + } + + unicorn::ScopeValues WeexGlobalBinding::callAddElement(const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + std::string page_id; + std::string parent_ref; + Args dom_str; + std::string index_str; + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, page_id); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 1, parent_ref); + WeexConversionUtils::GetWsonFromArgs(vars, 2, dom_str); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 3, index_str); + + LOG_WEEX_BINDING("[WeexGlobalBinding] [AddElementAction] doc:%s,parent:%s,index:%s", page_id.c_str(), + parent_ref.c_str(), + index_str.c_str()); + + nativeObject->js_bridge()->core_side()->AddElement( + page_id.c_str(), parent_ref.c_str(), dom_str.getValue(), + dom_str.getLength(), index_str.c_str()); + + return unicorn::RuntimeValues::MakeInt(0); + } + + unicorn::ScopeValues WeexGlobalBinding::callCreateBody(const std::vector &vars) { + + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + std::string page_id; + Args dom_str; + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, page_id); + WeexConversionUtils::GetWsonFromArgs(vars, 1, dom_str); + + LOG_WEEX_BINDING("[WeexGlobalBinding] [sendCreateBodyAction] doc:%s", page_id.c_str()); + + nativeObject->js_bridge()->core_side()->CreateBody(page_id.c_str(), dom_str.getValue(), + dom_str.getLength()); + return unicorn::RuntimeValues::MakeInt(0); + } + + + unicorn::ScopeValues WeexGlobalBinding::callUpdateFinish(const std::vector &vars) { + LOG_WEEX_BINDING("WeexGlobalBinding method :callUpdateFinish"); + + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + std::string page_id; + Args task_str; + Args call_back_str; + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, page_id); + WeexConversionUtils::GetWsonFromArgs(vars, 1, task_str); + WeexConversionUtils::GetWsonFromArgs(vars, 2, call_back_str); + + auto res = nativeObject->js_bridge()->core_side()->UpdateFinish(page_id.c_str(), task_str.getValue(), + task_str.getLength(), + call_back_str.getValue(), + call_back_str.getLength()); + return unicorn::RuntimeValues::MakeInt(res); + } + + unicorn::ScopeValues WeexGlobalBinding::callCreateFinish(const std::vector &vars) { + + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + std::string page_id; + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, page_id); + LOG_WEEX_BINDING("[WeexGlobalBinding] [sendCreateFinish] doc:%s, ", page_id.c_str()); + nativeObject->js_bridge()->core_side()->CreateFinish(page_id.c_str()); + return unicorn::RuntimeValues::MakeInt(0); + } + + unicorn::ScopeValues WeexGlobalBinding::callRefreshFinish(const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + + std::string page_id; + std::string task; + std::string callBack; + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, page_id); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 1, task); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 2, callBack); + + LOG_WEEX_BINDING("WeexGlobalBinding method :callRefreshFinish,argSize:%d, page:%s,task:%s,callback:%s", + vars.size(), + page_id.c_str(), task.c_str(), callBack.c_str() + ); + + auto result = nativeObject->js_bridge()->core_side()->RefreshFinish(page_id.c_str(), task.c_str(), + callBack.c_str()); + return unicorn::RuntimeValues::MakeInt(result); + } + + + unicorn::ScopeValues WeexGlobalBinding::callUpdateAttrs(const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + LOG_WEEX_BINDING("WeexGlobalBinding method :callUpdateAttrs"); + + std::string page_id; + std::string node_ref; + Args dom_attrs; + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, page_id); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 1, node_ref); + WeexConversionUtils::GetWsonFromArgs(vars, 2, dom_attrs); + + nativeObject->js_bridge()->core_side()->UpdateAttrs( + page_id.c_str(), + node_ref.c_str(), + dom_attrs.getValue(), + dom_attrs.getLength() + ); + return unicorn::RuntimeValues::MakeInt(0); + } + + unicorn::ScopeValues WeexGlobalBinding::callUpdateStyle(const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + + LOG_WEEX_BINDING("WeexGlobalBinding method :callUpdateStyle"); + + std::string page_id; + std::string node_ref; + Args dom_styles; + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, page_id); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 1, node_ref); + WeexConversionUtils::GetWsonFromArgs(vars, 2, dom_styles); + + nativeObject->js_bridge()->core_side()->UpdateStyle(page_id.c_str(), node_ref.c_str(), + dom_styles.getValue(), + dom_styles.getLength()); + + return unicorn::RuntimeValues::MakeInt(0); + } + + + unicorn::ScopeValues WeexGlobalBinding::callRemoveElement(const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + + LOG_WEEX_BINDING("WeexGlobalBinding method :callRemoveElement"); + + std::string page_id; + std::string node_ref; + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, page_id); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 1, node_ref); + + vars[0]->GetAsString(&page_id); + vars[1]->GetAsString(&node_ref); + nativeObject->js_bridge()->core_side()->RemoveElement(page_id.c_str(), node_ref.c_str()); + return unicorn::RuntimeValues::MakeInt(0); + } + + unicorn::ScopeValues WeexGlobalBinding::callMoveElement(const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + + LOG_WEEX_BINDING("WeexGlobalBinding method :callMoveElement"); + + std::string page_id; + std::string node_ref; + std::string parent_ref; + std::string index_char; + + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, page_id); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 1, node_ref); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 2, parent_ref); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 3, index_char); + + nativeObject->js_bridge()->core_side()->MoveElement( + page_id.c_str(), + node_ref.c_str(), + parent_ref.c_str(), + atoi(index_char.c_str()) + ); + return unicorn::RuntimeValues::MakeInt(0); + } + + unicorn::ScopeValues WeexGlobalBinding::callAddEvent(const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + + LOG_WEEX_BINDING("WeexGlobalBinding method :callAddEvent"); + + std::string page_id; + std::string node_ref; + std::string event; + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, page_id); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 1, node_ref); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 2, event); + + nativeObject->js_bridge()->core_side()->AddEvent( + page_id.c_str(), + node_ref.c_str(), + event.c_str() + ); + return unicorn::RuntimeValues::MakeInt(0); + } + + unicorn::ScopeValues WeexGlobalBinding::callRemoveEvent(const std::vector &vars) { + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + + LOG_WEEX_BINDING("WeexGlobalBinding method :callRemoveEvent"); + std::string page_id; + std::string node_ref; + std::string event; + + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, page_id); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 1, node_ref); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 2, event); + + nativeObject->js_bridge()->core_side()->RemoveEvent( + page_id.c_str(), + node_ref.c_str(), + event.c_str() + ); + return unicorn::RuntimeValues::MakeInt(0); + } + + + unicorn::ScopeValues WeexGlobalBinding::setTimeoutNative( + const std::vector &vars) { + + if (nullptr == nativeObject) { + return unicorn::RuntimeValues::MakeUndefined(); + } + + std::string callback_str; + std::string time_str; + + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, callback_str); + WeexConversionUtils::GetStringFromArgsDefaultEmpty(vars, 0, time_str); + + LOG_WEEX_BINDING("WeexGlobalBinding method :setTimeoutNative ,callback:%s, time:%d", + callback_str.c_str(), + time_str.c_str() + ); + + nativeObject->js_bridge()->core_side()->SetTimeout( + callback_str.c_str(), + time_str.c_str() + ); + return unicorn::RuntimeValues::MakeInt(0); + } + + unicorn::ScopeValues + WeexGlobalBinding::nativeLog(const std::vector &vars) { + return WeexBindingUtils::nativeLog(this->nativeObject, vars, true); + } + + unicorn::ScopeValues WeexGlobalBinding::notifyTrimMemory( + const std::vector &vars) { + LOG_WEEX_BINDING("WeexGlobalBinding method :notifyTrimMemory"); + +// JSLockHolder lock(exec); +// // exec->heap()->collectAllGarbage(); +// return JSValue::encode(jsNumber(exec->heap()->sizeAfterLastFullCollection())); + + return unicorn::RuntimeValues::MakeUndefined(); + } + + unicorn::ScopeValues + WeexGlobalBinding::markupState(const std::vector &vars) { + LOG_WEEX_BINDING("WeexGlobalBinding method :markupState"); + //not impl in old logic + return unicorn::RuntimeValues::MakeUndefined(); + } + + unicorn::ScopeValues + WeexGlobalBinding::atob(const std::vector &vars) { + return WeexBindingUtils::atob(this->nativeObject, vars); + } + + unicorn::ScopeValues + WeexGlobalBinding::btoa(const std::vector &vars) { + return WeexBindingUtils::btoa(this->nativeObject, vars); + } + + unicorn::ScopeValues WeexGlobalBinding::__updateComponentData( + const std::vector &vars) { + + return WeexBindingUtils::__updateComponentData(this->nativeObject, vars); + + } + } + +} diff --git a/weex_core/Source/js_runtime/weex/binding/weex_global_binding.h b/weex_core/Source/js_runtime/weex/binding/weex_global_binding.h new file mode 100644 index 0000000000..13579c0300 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/binding/weex_global_binding.h @@ -0,0 +1,114 @@ +/** + * 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 陈佩翰 on 2019/1/23. +// + +#ifndef PROJECT_WEEX_GLOBAL_OBJECT_H +#define PROJECT_WEEX_GLOBAL_OBJECT_H + + +#include "js_runtime/runtime/runtime_object.h" +#include "js_runtime/runtime/binding_macro.h" +#include "weex_console_binding.h" + +class WeexGlobalObjectV2; + +namespace weex { + namespace jsengine { + + + class WeexGlobalBinding : public unicorn::RuntimeObject { + public: + DECLARE_CLASS_REGISTER_OP(WeexGlobalBinding) + + WeexGlobalBinding(unicorn::EngineContext *context, const OpaqueJSContext *js_ctx); + + ~WeexGlobalBinding() override; + + public: + unicorn::ScopeValues callNative(const std::vector &vars); + + unicorn::ScopeValues + callNativeModule(const std::vector &vars); + + unicorn::ScopeValues + callNativeComponent(const std::vector &vars); + + + unicorn::ScopeValues + setTimeoutNative(const std::vector &vars); + + unicorn::ScopeValues nativeLog(const std::vector &vars); + + unicorn::ScopeValues + notifyTrimMemory(const std::vector &vars); + + unicorn::ScopeValues + markupState(const std::vector &vars); + + unicorn::ScopeValues atob(const std::vector &vars); + + unicorn::ScopeValues btoa(const std::vector &vars); + + unicorn::ScopeValues callCreateBody(const std::vector &vars); + + unicorn::ScopeValues callUpdateFinish(const std::vector &vars); + + unicorn::ScopeValues callCreateFinish(const std::vector &vars); + + unicorn::ScopeValues callRefreshFinish(const std::vector &vars); + + unicorn::ScopeValues callUpdateAttrs(const std::vector &vars); + + unicorn::ScopeValues callUpdateStyle(const std::vector &vars); + + unicorn::ScopeValues callAddElement(const std::vector &vars); + + unicorn::ScopeValues callRemoveElement(const std::vector &vars); + + unicorn::ScopeValues callMoveElement(const std::vector &vars); + + unicorn::ScopeValues callAddEvent(const std::vector &vars); + + unicorn::ScopeValues callRemoveEvent(const std::vector &vars); + + unicorn::ScopeValues + callGCanvasLinkNative(const std::vector &vars); + + unicorn::ScopeValues + setIntervalWeex(const std::vector &vars); + + unicorn::ScopeValues + clearIntervalWeex(const std::vector &vars); + + unicorn::ScopeValues + callT3DLinkNative(const std::vector &vars); + + unicorn::ScopeValues + __updateComponentData(const std::vector &vars); + + public: + WeexGlobalObjectV2 *nativeObject = nullptr; + + }; + } +} + +#endif //PROJECT_WEEX_GLOBAL_OBJECT_H diff --git a/weex_core/Source/js_runtime/weex/binding/weex_instance_binding.cpp b/weex_core/Source/js_runtime/weex/binding/weex_instance_binding.cpp new file mode 100644 index 0000000000..3d819623cd --- /dev/null +++ b/weex_core/Source/js_runtime/weex/binding/weex_instance_binding.cpp @@ -0,0 +1,152 @@ +/** + * 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 陈佩翰 on 2019/1/23. +// + +#include "weex_instance_binding.h" +#include "js_runtime/utils/log_utils.h" +#include "js_runtime/weex/object/weex_global_object_v2.h" +#include "core/bridge/script_bridge.h" +#include "weex_binding_utils.h" + +namespace weex { + namespace jsengine { + + CLASS_METHOD_CALLBACK(WeexInstanceBinding, nativeLog) + + CLASS_METHOD_CALLBACK(WeexInstanceBinding, atob) + + CLASS_METHOD_CALLBACK(WeexInstanceBinding, btoa) + + CLASS_METHOD_CALLBACK(WeexInstanceBinding, callGCanvasLinkNative) + + CLASS_METHOD_CALLBACK(WeexInstanceBinding, callT3DLinkNative) + + CLASS_METHOD_CALLBACK(WeexInstanceBinding, setNativeTimeout) + + CLASS_METHOD_CALLBACK(WeexInstanceBinding, setNativeInterval) + + CLASS_METHOD_CALLBACK(WeexInstanceBinding, clearNativeTimeout) + + CLASS_METHOD_CALLBACK(WeexInstanceBinding, clearNativeInterval) + + CLASS_MEMBER_GET_CALLBACK(WeexInstanceBinding, console) + + CLASS_METHOD_CALLBACK(WeexInstanceBinding, __updateComponentData) + + CLASS_REGISTER_START(WeexInstanceBinding, Instance) + SET_IS_GLOBAL + REGISTER_METHOD_CALLBACK(WeexInstanceBinding, nativeLog) + REGISTER_METHOD_CALLBACK(WeexInstanceBinding, atob) + REGISTER_METHOD_CALLBACK(WeexInstanceBinding, btoa) + REGISTER_METHOD_CALLBACK(WeexInstanceBinding, callGCanvasLinkNative) + REGISTER_METHOD_CALLBACK(WeexInstanceBinding, callT3DLinkNative) + REGISTER_METHOD_CALLBACK(WeexInstanceBinding, setNativeTimeout) + REGISTER_METHOD_CALLBACK(WeexInstanceBinding, setNativeInterval) + REGISTER_METHOD_CALLBACK(WeexInstanceBinding, clearNativeTimeout) + REGISTER_METHOD_CALLBACK(WeexInstanceBinding, clearNativeInterval) + REGISTER_METHOD_CALLBACK(WeexInstanceBinding, __updateComponentData) + REGISTER_GET_CALLBACK(WeexInstanceBinding, console) + CLASS_REGISTER_END(WeexInstanceBinding) + + + WeexInstanceBinding::WeexInstanceBinding(unicorn::EngineContext *context, const OpaqueJSContext *js_ctx) + : RuntimeObject(context, js_ctx) { + //SetJSClass(WeexInstanceBinding::s_jsclass_WeexInstanceBinding); + LOG_WEEX_BINDING("WeexInstanceBinding init"); + consoleBinding.reset(new WeexConsoleBinding(context, js_ctx)); + SetJSClass(weex::jsengine::WeexInstanceBinding::CreateClassRef(context)); + } + + WeexInstanceBinding::~WeexInstanceBinding() { + LOG_WEEX_BINDING("[release] WeexInstanceBinding delete"); + this->nativeObject = nullptr; + + } + + unicorn::ScopeValues + WeexInstanceBinding::nativeLog(const std::vector &vars) { + return WeexBindingUtils::nativeLog(this->nativeObject, vars, false); + } + + unicorn::ScopeValues + WeexInstanceBinding::atob(const std::vector &vars) { + return WeexBindingUtils::atob(this->nativeObject, vars); + } + + unicorn::ScopeValues + WeexInstanceBinding::btoa(const std::vector &vars) { + return WeexBindingUtils::btoa(this->nativeObject, vars); + } + + unicorn::ScopeValues WeexInstanceBinding::callGCanvasLinkNative( + const std::vector &vars) { + LOG_WEEX_BINDING("WeexInstanceBinding method :callGCanvasLinkNative"); + return WeexBindingUtils::callGCanvasLinkNative(nativeObject, vars); + } + + unicorn::ScopeValues WeexInstanceBinding::callT3DLinkNative( + const std::vector &vars) { + LOG_WEEX_BINDING("WeexInstanceBinding method :callT3DLinkNative"); + return WeexBindingUtils::callT3DLinkNative(nativeObject, vars); + } + + unicorn::ScopeValues WeexInstanceBinding::setNativeTimeout( + std::vector &vars) { + LOG_WEEX_BINDING("instanceConteext: setNativeTimeout this:%p,nativeObject:%p", this,nativeObject); + return WeexBindingUtils::setNativeTimeout(nativeObject, vars, false); + } + + unicorn::ScopeValues WeexInstanceBinding::setNativeInterval( + std::vector &vars) { + LOG_WEEX_BINDING("instanceConteext: setNativeInterval this:%p,nativeObject:%p", this,nativeObject); + return WeexBindingUtils::setNativeTimeout(nativeObject, vars, true); + } + + unicorn::ScopeValues WeexInstanceBinding::clearNativeTimeout( + std::vector &vars) { + return WeexBindingUtils::clearNativeTimeout(this->nativeObject, vars); + } + + unicorn::ScopeValues WeexInstanceBinding::clearNativeInterval( + std::vector &vars) { + return WeexBindingUtils::clearNativeTimeout(this->nativeObject, vars); + } + + unicorn::ScopeValues WeexInstanceBinding::console() { + LOG_WEEX_BINDING("[console] WeexInstanceBinding console :%p",this->consoleBinding.get()); + if (nullptr == nativeObject || nullptr == this->consoleBinding.get()){ + return unicorn::RuntimeValues::MakeUndefined(); + } + return unicorn::RuntimeValues::MakeCommonObject( + static_cast(this->consoleBinding.get()), + new unicorn::RuntimeClass(consoleBinding->GetJSClass()) + ); + } + + unicorn::ScopeValues WeexInstanceBinding::__updateComponentData( + const std::vector &vars) { + LOG_WEEX_BINDING("WeexInstanceBinding method :__updateComponentData"); + return WeexBindingUtils::__updateComponentData(this->nativeObject,vars); + } + } +} + + diff --git a/weex_core/Source/js_runtime/weex/binding/weex_instance_binding.h b/weex_core/Source/js_runtime/weex/binding/weex_instance_binding.h new file mode 100644 index 0000000000..a0fe8838f4 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/binding/weex_instance_binding.h @@ -0,0 +1,80 @@ +/** + * 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 陈佩翰 on 2019/1/23. +// + +#ifndef PROJECT_WEEX_INSTANCE_OBJECT_H +#define PROJECT_WEEX_INSTANCE_OBJECT_H + +#include "js_runtime/runtime/runtime_object.h" +#include "js_runtime/runtime/binding_macro.h" +#include "weex_console_binding.h" + + +class WeexGlobalObjectV2; + +namespace weex { + namespace jsengine { + + + class WeexInstanceBinding : public unicorn::RuntimeObject { + public: + DECLARE_CLASS_REGISTER_OP(WeexInstanceBinding) + + WeexInstanceBinding(unicorn::EngineContext *context, const OpaqueJSContext *js_ctx); + + ~WeexInstanceBinding() override; + + unicorn::ScopeValues nativeLog(const std::vector &vars); + + unicorn::ScopeValues atob(const std::vector &vars); + + unicorn::ScopeValues btoa(const std::vector &vars); + + unicorn::ScopeValues + callGCanvasLinkNative(const std::vector &vars); + + unicorn::ScopeValues + callT3DLinkNative(const std::vector &vars); + + unicorn::ScopeValues + setNativeTimeout(std::vector &vars); + + unicorn::ScopeValues + setNativeInterval(std::vector &vars); + + unicorn::ScopeValues + clearNativeTimeout(std::vector &vars); + + unicorn::ScopeValues + clearNativeInterval(std::vector &vars); + + unicorn::ScopeValues console(); + + unicorn::ScopeValues + __updateComponentData(const std::vector &vars); + + public: + WeexGlobalObjectV2* nativeObject = nullptr; + std::unique_ptr consoleBinding; + }; + } +} +#endif //PROJECT_WEEX_INSTANCE_OBJECT_H diff --git a/weex_core/Source/js_runtime/weex/bridge/script/script_side_in_queue.cpp b/weex_core/Source/js_runtime/weex/bridge/script/script_side_in_queue.cpp new file mode 100644 index 0000000000..6295d62499 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/bridge/script/script_side_in_queue.cpp @@ -0,0 +1,358 @@ +/** + * 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 "android/jsengine/object/weex_env.h" +#include "android/jsengine/bridge/script/script_side_in_queue.h" + +#include "js_runtime/weex/task/impl/init_framework_task.h" +#include "js_runtime/weex/task/impl/create_app_context_task.h" +#include "js_runtime/weex/task/impl/create_instance_task.h" +#include "js_runtime/weex/task/impl/call_js_on_app_context_task.h" +#include "js_runtime/weex/task/impl/destory_app_context_task.h" +#include "js_runtime/weex/task/impl/destory_instance_task.h" +#include "js_runtime/weex/task/impl/exe_js_on_app_with_result.h" +#include "js_runtime/weex/task/impl/update_global_config_task.h" +#include "js_runtime/weex/task/impl/update_init_framework_params_task.h" +#include "js_runtime/weex/task/impl/ctime_callback_task.h" +#include "js_runtime/weex/task/impl/exe_js_services_task.h" +#include "js_runtime/weex/task/impl/exe_js_on_instance_task.h" +#include "js_runtime/weex/task/impl/exe_js_task.h" +#include "js_runtime/weex/task/impl/take_heap_snapshot.h" +#include "js_runtime/weex/task/impl/native_timer_task.h" + +namespace weex { +namespace bridge { +namespace js { +int ScriptSideInQueue::InitFramework( + const char *script, std::vector ¶ms) { + LOGD("ScriptSideInQueue::InitFramework"); + weexTaskQueue_->addTask(new InitFrameworkTask(char2String(script), params)); + weexTaskQueue_->init(); + + if (WeexEnv::getEnv()->enableBackupThread()) { + WeexEnv::getEnv()->locker()->lock(); + while (!WeexEnv::getEnv()->is_jsc_init_finished()) { + WeexEnv::getEnv()->locker()->wait(); + } + WeexEnv::getEnv()->locker()->unlock(); + + if(WeexEnv::getEnv()->can_m_cache_task_()) { + WeexEnv::getEnv()->m_task_cache_.push_back(new InitFrameworkTask(char2String(script), params)); + LOGE("cache initFramework %d", WeexEnv::getEnv()->m_task_cache_.size()); + } else { + weexTaskQueue_bk_ = new WeexTaskQueue(weexTaskQueue_->isMultiProgress); + weexTaskQueue_bk_->addTask(new InitFrameworkTask(char2String(script), params)); + weexTaskQueue_bk_->init(); + } + + } + + return 1; +} + +int ScriptSideInQueue::InitAppFramework( + const char *instanceId, const char *appFramework, + std::vector ¶ms) { + LOGD("ScriptSideInQueue::InitAppFramework"); + weexTaskQueue_->addTask(new InitFrameworkTask(instanceId, appFramework, params)); + return 1; + +} + +int ScriptSideInQueue::CreateAppContext(const char *instanceId, + const char *jsBundle) { + LOGD("ScriptSideInQueue::CreateAppContext"); + if (jsBundle == nullptr || strlen(jsBundle) == 0) { + return 0; + } + weexTaskQueue_->addTask(new CreateAppContextTask(instanceId, jsBundle)); + return 1; +} + +std::unique_ptr ScriptSideInQueue::ExecJSOnAppWithResult(const char *instanceId, + const char *jsBundle) { + LOGD("ScriptSideInQueue::ExecJSOnAppWithResult"); + + WeexTask *task = new ExeJsOnAppWithResultTask((instanceId), + (jsBundle)); + + auto future = std::unique_ptr(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 ¶ms) { + LOGD("ScriptSideInQueue::CallJSOnAppContext"); + + weexTaskQueue_->addTask(new CallJsOnAppContextTask(instanceId, + func, params)); + + return 1; +} + +int ScriptSideInQueue::DestroyAppContext(const char *instanceId) { + LOGE("ScriptSideInQueue::DestroyAppContext"); + + weexTaskQueue_->addTask(new DestoryAppContextTask(instanceId)); + + return 1; +} + +int ScriptSideInQueue::ExecJsService(const char *source) { + LOGD("ScriptSideInQueue::ExecJsService"); + + weexTaskQueue_->addTask(new ExeJsServicesTask((source))); + if (WeexEnv::getEnv()->enableBackupThread()) { + ExeJsServicesTask *task = new ExeJsServicesTask((source)); + if(WeexEnv::getEnv()->can_m_cache_task_() && weexTaskQueue_bk_ == nullptr){ + WeexEnv::getEnv()->m_task_cache_.push_back(task); + LOGE("cache ExecJsService %d", WeexEnv::getEnv()->m_task_cache_.size()); + } else { + weexTaskQueue_bk_->addTask(task); + } + + } + + return 1; +} + +int ScriptSideInQueue::ExecTimeCallback(const char *source) { + LOGD("ScriptSideInQueue::ExecTimeCallback"); + + weexTaskQueue_->addTask(new CTimeCallBackTask(char2String(source))); + if (WeexEnv::getEnv()->enableBackupThread() && weexTaskQueue_bk_ != nullptr) { + weexTaskQueue_bk_->addTask(new CTimeCallBackTask(char2String(source))); + } + + return 1; +} + +int ScriptSideInQueue::ExecJS(const char *instanceId, const char *nameSpace, + const char *func, + std::vector ¶ms) { + LOGD("ScriptSideInQueue::ExecJS"); + ExeJsTask *task = new ExeJsTask(char2String(instanceId), params); + + task->addExtraArg(char2String(nameSpace)); + task->addExtraArg(char2String(func)); + + if (instanceId == nullptr || strlen(instanceId) == 0) { + if (WeexEnv::getEnv()->enableBackupThread()) { + if(WeexEnv::getEnv()->can_m_cache_task_() && weexTaskQueue_bk_ == nullptr){ + WeexEnv::getEnv()->m_task_cache_.push_back(task->clone()); + LOGE("cache ExecJS %d", WeexEnv::getEnv()->m_task_cache_.size()); + } else { + weexTaskQueue_bk_->addTask(task->clone()); + } + } + + weexTaskQueue_->addTask(task); + } else { + taskQueue(instanceId, false)->addTask(task); + } + return 1; +} + +std::unique_ptr ScriptSideInQueue::ExecJSWithResult( + const char *instanceId, const char *nameSpace, const char *func, + std::vector ¶ms) { + LOGD("ScriptSideInQueue::ExecJSWithResult"); + + ExeJsTask *task = new ExeJsTask(char2String(instanceId), params, true); + + auto future = std::unique_ptr(new WeexTask::Future()); + task->set_future(future.get()); + + task->addExtraArg(char2String(nameSpace)); + task->addExtraArg(char2String(func)); + taskQueue(instanceId, false)->addTask(task); + return std::move(future->waitResult()); +} + +void ScriptSideInQueue::ExecJSWithCallback( + const char *instanceId, const char *nameSpace, const char *func, + std::vector ¶ms, long callback_id) { + LOGD("ScriptSideInQueue::ExecJSWithCallback"); + + ExeJsTask *task = new ExeJsTask(char2String(instanceId), params, callback_id); + + task->addExtraArg(char2String(nameSpace)); + task->addExtraArg(char2String(func)); + taskQueue(instanceId, false)->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 ¶ms) { + LOGD( + "CreateInstance id = %s, func = %s, script = %s, opts = %s, initData = " + "%s, extendsApi = %s", + instanceId, func, script, opts, initData, extendsApi); + if (script == nullptr || strlen(script) == 0) { + return 0; + } + + bool backUpThread = false; + if (WeexEnv::getEnv()->enableBackupThread()) { + for (int i = 0; i < params.size(); ++i) { + auto param = params[i]; + std::string type = param->type->content; + std::string value = param->value->content; + if (type == "use_back_thread") { + if (value == "true") { + backUpThread = true; + } + break; + } + } + } + + if(backUpThread) { + useBackUpWeexRuntime(instanceId); + } + + CreateInstanceTask *task = new CreateInstanceTask(char2String(instanceId), + script, params); + + task->addExtraArg(char2String(func)); + task->addExtraArg(char2String(opts)); + task->addExtraArg(char2String(initData)); + task->addExtraArg(char2String(extendsApi)); + auto pQueue = taskQueue(instanceId, true); + pQueue->addTask(task); + if (!pQueue->isInitOk) { + pQueue->init(); + } + return 1; +} + +std::unique_ptr ScriptSideInQueue::ExecJSOnInstance(const char *instanceId, + const char *script,int type) { + LOGD("ScriptSideInQueue::ExecJSOnInstance"); + ExeJsOnInstanceTask *task = new ExeJsOnInstanceTask(instanceId, + script); + taskQueue(instanceId, false)->addTask(task); + if (type == -1){ + //don't need wait. just run js. + std::unique_ptr returnResult; + returnResult.reset(new WeexJSResult()); + LOGE("test-> return default result"); + return returnResult; + } + auto future = std::unique_ptr(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); + taskQueue(instanceId, + false)->addTask(new DestoryInstanceTask(instanceId)); + deleteBackUpRuntimeInstance(instanceId); + return 1; +} + +int ScriptSideInQueue::UpdateGlobalConfig(const char *config) { + LOGD("ScriptSideInQueue::UpdateGlobalConfig"); + weexTaskQueue_->addTask(new UpdateGlobalConfigTask(config)); + if (WeexEnv::getEnv()->enableBackupThread() && weexTaskQueue_bk_ != nullptr) { + weexTaskQueue_bk_->addTask(new UpdateGlobalConfigTask(config)); + } + + return 1; +} + +int ScriptSideInQueue::UpdateInitFrameworkParams(const std::string& key, const std::string& value, const std::string& desc){ + LOGD("ScriptSideInQueue::UpdateInitFrameworkParams"); + weexTaskQueue_->addTask(new UpdateInitFrameworkParamsTask(key, value, desc)); + if (WeexEnv::getEnv()->enableBackupThread()) { + UpdateInitFrameworkParamsTask* task = new UpdateInitFrameworkParamsTask(key, value, desc); + if(WeexEnv::getEnv()->can_m_cache_task_() && weexTaskQueue_bk_ == nullptr){ + WeexEnv::getEnv()->m_task_cache_.push_back(task); + } else { + weexTaskQueue_bk_->addTask(task); + } + } + + return 1; +} + +void ScriptSideInQueue::useBackUpWeexRuntime(std::string id) { + usingBackThreadId.push_back(id); +} + +bool ScriptSideInQueue::shouldUseBackUpWeexRuntime(std::string id) { + if (id.empty() || !WeexEnv::getEnv()->enableBackupThread()) + return false; + auto iter = std::find(usingBackThreadId.begin(), usingBackThreadId.end(), id); + return iter != usingBackThreadId.end(); +} + +void ScriptSideInQueue::deleteBackUpRuntimeInstance(std::string id) { + if (!WeexEnv::getEnv()->enableBackupThread()) { + return; + } + + auto iter = std::find(usingBackThreadId.begin(), usingBackThreadId.end(), id); + if (iter != usingBackThreadId.end()) { + usingBackThreadId.erase(iter); + } +} + +WeexTaskQueue *ScriptSideInQueue::taskQueue(const char *id, bool log) { + if (!WeexEnv::getEnv()->enableBackupThread()) { + return weexTaskQueue_; + } + + if (id != nullptr && shouldUseBackUpWeexRuntime(id)) { + if (weexTaskQueue_bk_ == nullptr) { + weexTaskQueue_bk_ = new WeexTaskQueue(weexTaskQueue_->isMultiProgress); + WeexEnv::getEnv()->set_m_cache_task_(false); + for (std::deque::iterator it = WeexEnv::getEnv()->m_task_cache_.begin(); it < WeexEnv::getEnv()->m_task_cache_.end(); ++it) { + auto reference = *it; + weexTaskQueue_bk_->addTask(std::move(reference)); + } + WeexEnv::getEnv()->m_task_cache_.clear(); + } + if (log) { + LOGE("dyyLog instance %s use back up thread time is %lld", id, microTime()); + } + return weexTaskQueue_bk_; + } + if (log && id != nullptr) { + LOGE("dyyLog instance %s use main thread time is %lld", id, microTime()); + } + return weexTaskQueue_; +} +} // namespace js +} // namespace bridge + +} // namespace weex diff --git a/weex_core/Source/js_runtime/weex/bridge/script/script_side_in_simple.cpp b/weex_core/Source/js_runtime/weex/bridge/script/script_side_in_simple.cpp new file mode 100644 index 0000000000..94bb88802e --- /dev/null +++ b/weex_core/Source/js_runtime/weex/bridge/script/script_side_in_simple.cpp @@ -0,0 +1,150 @@ +/** + * 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_side_in_simple.h" +#include "js_runtime/weex/object/weex_runtime.h" + +namespace weex { +namespace bridge { +namespace js { +int ScriptSideInSimple::InitFramework( + const char *script, std::vector ¶ms) { + LOGD("ScriptSideInSimple::InitFramework"); + + return runtime_->initFramework(std::string(script), params); +} + +int ScriptSideInSimple::InitAppFramework( + const char *instanceId, const char *appFramework, + std::vector ¶ms) { + LOGD("ScriptSideInSimple::InitAppFramework"); + return runtime_->initAppFramework(std::string(instanceId), + std::string(appFramework), params); +} + +int ScriptSideInSimple::CreateAppContext(const char *instanceId, + const char *jsBundle) { + LOGD("ScriptSideInSimple::CreateAppContext"); + return runtime_->createAppContext(std::string(instanceId), + std::string(jsBundle)); +} + +std::unique_ptr ScriptSideInSimple::ExecJSOnAppWithResult(const char *instanceId, + const char *jsBundle) { + LOGD("ScriptSideInSimple::ExecJSOnAppWithResult"); + return runtime_->exeJSOnAppWithResult(std::string(instanceId), + std::string(jsBundle)); +} + +int ScriptSideInSimple::CallJSOnAppContext( + const char *instanceId, const char *func, + std::vector ¶ms) { + LOGD("ScriptSideInSimple::CallJSOnAppContext"); + return runtime_->callJSOnAppContext(std::string(instanceId), + std::string(func), params); +} + +int ScriptSideInSimple::DestroyAppContext(const char *instanceId) { + LOGD("ScriptSideInSimple::DestroyAppContext"); + return runtime_->destroyAppContext(std::string(instanceId)); +} + +int ScriptSideInSimple::ExecJsService(const char *source) { + LOGD("ScriptSideInSimple::ExecJsService"); + return runtime_->exeJsService(std::string(source)); +} + +int ScriptSideInSimple::ExecTimeCallback(const char *source) { + LOGD("ScriptSideInSimple::ExecTimeCallback"); + return runtime_->exeCTimeCallback(std::string(source)); +} + +int ScriptSideInSimple::ExecJS(const char *instanceId, const char *nameSpace, + const char *func, + std::vector ¶ms) { + LOGD("ScriptSideInSimple::ExecJS"); + return runtime_->exeJS(std::string(instanceId), + std::string(nameSpace), std::string(func), + params); +} + +std::unique_ptr ScriptSideInSimple::ExecJSWithResult( + const char *instanceId, const char *nameSpace, const char *func, + std::vector ¶ms) { + LOGD("ScriptSideInSimple::ExecJSWithResult"); + return runtime_->exeJSWithResult(std::string(instanceId), + std::string(nameSpace), + std::string(func), params); +} + +void ScriptSideInSimple::ExecJSWithCallback( + const char *instanceId, const char *nameSpace, const char *func, + std::vector ¶ms, long callback_id) { + LOGD("ScriptSideInSimple::ExecJSWithResult"); + runtime_->exeJSWithResult(std::string(instanceId), + std::string(nameSpace), + std::string(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& params) { + LOGD( + "CreateInstance id = %s, func = %s, script = %s, opts = %s, initData = " + "%s, extendsApi = %s", + instanceId, func, script, opts, initData, extendsApi); + + return runtime_->createInstance( + std::string(instanceId), std::string(func), + std::string(script), std::string(opts), + std::string(initData), std::string(extendsApi),params); +} + +std::unique_ptr ScriptSideInSimple::ExecJSOnInstance(const char *instanceId, + const char *script,int type) { + LOGD("ScriptSideInSimple::ExecJSOnInstance"); + return runtime_->exeJSOnInstance(std::string(instanceId), + std::string(script)); +} + +int ScriptSideInSimple::DestroyInstance(const char *instanceId) { + LOGD("ScriptSideInSimple::DestroyInstance"); + return runtime_->destroyInstance(std::string(instanceId)); +} + +int ScriptSideInSimple::UpdateGlobalConfig(const char *config) { + LOGD("ScriptSideInSimple::UpdateGlobalConfig"); + return runtime_->updateGlobalConfig(std::string(config)); +} + + +int ScriptSideInSimple::UpdateInitFrameworkParams(const std::string& key, const std::string& value, const std::string& desc){ + LOGD("ScriptSideInSimple::UpdateInitFrameworkParams"); + return runtime_->UpdateInitFrameworkParams(key ,value, desc); +} + + + +} // namespace js +} // namespace bridge +} // namespace weex diff --git a/weex_core/Source/js_runtime/weex/object/args.h b/weex_core/Source/js_runtime/weex/object/args.h new file mode 100644 index 0000000000..dbecd62cdf --- /dev/null +++ b/weex_core/Source/js_runtime/weex/object/args.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. + */ +// +// Created by jianbai.gbj on 15/05/2018. +// + +#ifndef ARGS_H +#define ARGS_H + +#include + +#include "wson/wson.h" + +/** + * auto conver for json and wson + */ +namespace WeexCore { + static const int ARGS_TYPE_JSON = 0; + static const int ARGS_TYPE_WSON = 1; + class Args{ + public: + Args(); + ~Args(); + + int getType(){ + return type; + }; + + void setString(std::string& string){ + this->json = string; + this->type = ARGS_TYPE_JSON; + // if string is not utf8, we convert it + utf8.assign(json.c_str()); + } + /**object will auto free when args destructor */ + void setWson(wson_buffer* buffer){ + this->wson = buffer; + this->type = ARGS_TYPE_WSON; + } + + inline const char* getValue() const { + if(type == ARGS_TYPE_WSON){ + if(wson){ + return (char*)(wson->data); + } + return nullptr; + }else{ + return utf8.c_str(); + } + } + + inline int getLength() const { + if(type == ARGS_TYPE_WSON){ + if(wson){ + return (wson->position); + } + return 0; + }else{ + return strlen(json.c_str()); + } + } + + private: + int type; + public: + std::string json; + std::string utf8; + wson_buffer* wson = nullptr; + }; +}; + +#endif diff --git a/weex_core/Source/js_runtime/weex/object/weex_global_object_v2.cpp b/weex_core/Source/js_runtime/weex/object/weex_global_object_v2.cpp new file mode 100644 index 0000000000..af8586206b --- /dev/null +++ b/weex_core/Source/js_runtime/weex/object/weex_global_object_v2.cpp @@ -0,0 +1,245 @@ +/** + * 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 陈佩翰 on 2019/2/22. +// + +#include "core/bridge/script_bridge.h" +#include "js_runtime/weex/utils/weex_jsc_utils.h" +#include "core/bridge/script_bridge.h" +#include "js_runtime/weex/binding/weex_global_binding.h" +#include "js_runtime/weex/binding/weex_instance_binding.h" +#include "js_runtime/weex/binding/app_context_binding.h" +#include "weex_global_object_v2.h" +#include "js_runtime/utils/log_utils.h" +#include "js_runtime/weex/utils/weex_conversion_utils.h" + +static bool isGlobalConfigStartUpSet = false; +#define WX_GLOBAL_CONFIG_KEY "global_switch_config" + +void WeexGlobalObjectV2::makeWeexGlobalObject(unicorn::RuntimeVM *vm) { + this->object_type_ = WeexGlobal; + auto binding_object = new weex::jsengine::WeexGlobalBinding(nullptr, nullptr); + context = unicorn::RuntimeContext::Create(vm, binding_object->GetJSClass()); + binding_object->SetEngineContext(context->GetEngineContext()); + LOG_RUNTIME("[Context] makeWeexGlobalObject context ptr:%p", context->GetEngineContext()->GetContext()); + auto global_js_object = context->GetEngineContext()->GetGlobalObjectInContext(); + context->GetEngineContext()->BindDataToObject(global_js_object, binding_object); + binding_object->SetJSObject(global_js_object); + binding_object->nativeObject = this; + this->global_object_binding.reset(static_cast(binding_object)); + //binding dom api + //weex::jsengine::DomManager::BindingDomApi(context->GetEngineContext(), std::string("global"),std::string("weex_global_context")); +} + +void +WeexGlobalObjectV2::makeWeexInstanceObject(unicorn::RuntimeVM *vm, const std::string &id, const std::string &name) { + this->object_type_ = WeexInstance; + //global object not support bind static method for globalObject now cause jsruntime + auto binding_object = new weex::jsengine::WeexInstanceBinding(nullptr, nullptr); + context = unicorn::RuntimeContext::Create(vm, binding_object->GetJSClass()); + binding_object->SetEngineContext(context->GetEngineContext()); + context->GetEngineContext()->SetName(id); + binding_object->nativeObject = this; + auto global_js_object = context->GetEngineContext()->GetGlobalObjectInContext(); + context->GetEngineContext()->BindDataToObject(global_js_object, binding_object); + binding_object->SetJSObject(global_js_object); + this->global_object_binding.reset(static_cast(binding_object)); +} + +void WeexGlobalObjectV2::makeAppWorkerObject(unicorn::RuntimeVM *vm) { + this->object_type_ = AppWorker; + //global object not support bind static method for globalObject now cause jsruntime + auto binding_object = new weex::jsengine::AppWorkerBinding(nullptr, nullptr); + context = unicorn::RuntimeContext::Create(vm, binding_object->GetJSClass()); + binding_object->SetEngineContext(context->GetEngineContext()); + auto global_js_object = context->GetEngineContext()->GetGlobalObjectInContext(); + context->GetEngineContext()->BindDataToObject(global_js_object, binding_object); + binding_object->nativeObject = this; + binding_object->SetJSObject(global_js_object); + this->global_object_binding.reset(static_cast(binding_object)); +} + +void WeexGlobalObjectV2::addExtraOptions(std::vector ¶ms) { + if (params.size() <= 0) { + return; + } + std::unique_ptr wxExtraOption = unicorn::Map::CreateFromNative(this->context->GetEngineContext(), + unicorn::RuntimeValues::MakeNull()); + for (int i = 0; i < params.size(); i++) { + INIT_FRAMEWORK_PARAMS *param = params[i]; + wxExtraOption->Insert( + std::string(param->type->content), + new unicorn::RuntimeValues(param->value->content, param->value->length) + ); + + } + this->context->GetEngineContext()->SetGlobalPropertyValue( + std::string("WXExtraOption"), + unicorn::RuntimeValues::MakeMap(std::move(wxExtraOption)) + ); +} + +void +WeexGlobalObjectV2::initWxEnvironment(std::vector ¶ms, bool isSave) { + std::unique_ptr wxEnvironment = unicorn::Map::CreateFromNative(this->context->GetEngineContext(), + unicorn::RuntimeValues::MakeNull()); + for (int i = 0; i < params.size(); i++) { + INIT_FRAMEWORK_PARAMS *param = params[i]; + + std::string &&type = std::string(param->type->content); + std::string &&value = std::string(param->value->content); + if (isSave) { + auto init_framework_params = (INIT_FRAMEWORK_PARAMS *) malloc(sizeof(INIT_FRAMEWORK_PARAMS)); + + if (init_framework_params == nullptr) { + return; + } + + memset(init_framework_params, 0, sizeof(INIT_FRAMEWORK_PARAMS)); + init_framework_params->type = genWeexByteArraySS(param->type->content, param->type->length); + init_framework_params->value = genWeexByteArraySS(param->value->content, param->value->length); + + m_initFrameworkParams.push_back(init_framework_params); + } + + if (!isGlobalConfigStartUpSet) { + if (strncmp(type.c_str(), WX_GLOBAL_CONFIG_KEY, strlen(WX_GLOBAL_CONFIG_KEY)) == 0) { + const char *config = value.c_str(); + doUpdateGlobalSwitchConfig(config); + } + isGlobalConfigStartUpSet = true; + } + + // -------------------------------------------------------- + // add for debug mode + if (std::string("debugMode") == type && std::string("true") == value) { + // Weex::LogUtil::setDebugMode(true); + WeexCore::DebugMode = true; + LOGE("jss use %s","runtime"); + } + // -------------------------------------------------------- + + //LOGE("initWxEnvironment and value is %s", value.c_str()); + // addstd::string(vm, WXEnvironment, param->type->content, WTFMove(value)); + //LOGD("initWxEnvironment initWxEnvironment key:%s ,vaule: %s", type.c_str(), value.c_str()); + wxEnvironment->Insert(std::string(type.c_str()), + new unicorn::RuntimeValues(std::string(value.c_str()))); + //free(params); + } + const char *key = object_type_ == AppWorker ? "__windmill_environment__" : "WXEnvironment"; + + this->context->GetEngineContext()->SetGlobalPropertyValue( + std::string(key), + unicorn::RuntimeValues::MakeMap(std::move(wxEnvironment)) + ); +} + +void WeexGlobalObjectV2::setScriptBridge(WeexCore::ScriptBridge *script_bridge) { + this->script_bridge_ = script_bridge; +} + + +unicorn::RuntimeValues *WeexGlobalObjectV2::removeTimer(uint32_t function_id) { + auto iter = function_maps_.find(function_id); + if (iter == function_maps_.end()) { + LOGE("timer do not exist!"); + return nullptr; + } + auto funcValue = function_maps_[function_id]; + function_maps_.erase(function_id); + return funcValue; +} + +//uint32_t WeexGlobalObjectV2::genFunctionID() { +// if (function_id_ > (INT_MAX - 1)) { +// LOGE(" WeexGlobalObject::genFunctionID timer fucntion id to large, something wrong now, crash!"); +// abort(); +// } +// return function_id_++; +//} + +unicorn::RuntimeValues *WeexGlobalObjectV2::getTimerFunction(uint32_t function_id) { + auto iter = function_maps_.find(function_id); + if (iter == function_maps_.end()) + return nullptr; + return function_maps_[function_id]; +} + +void WeexGlobalObjectV2::updateInitFrameworkParams(const std::string &key, + const std::string &value) { + + LOGE("updateInitFrameworkParams %s %s ", key.data(), value.data()); + for(INIT_FRAMEWORK_PARAMS* param : m_initFrameworkParams){ + if(key.length() == param->type->length){ + if(strncmp(key.data(), param->type->content, key.length()) == 0){ + WeexByteArray * oldValue = param->value; + param->value = genWeexByteArraySS(value.data(), value.length()); + free(oldValue); + } + } + } +} + +//void WeexGlobalObjectV2::addTimer(uint32_t function_id, unicorn::RuntimeValues *func) { +// +// auto iter = function_maps_.find(function_id); +// if (iter != function_maps_.end()) { +// LOGE("timer already exist in map, return now"); +// return; +// } +// function_maps_[function_id] = func; +// +//} + +int WeexGlobalObjectV2::setNativeTimeout(unicorn::RuntimeValues *func, int timeOut, bool interval) { + if (nullptr == func || nullptr == timeQueue) { + return 0; + } + if (function_id_ > (INT_MAX - 1)) { + LOGE(" WeexGlobalObject::genFunctionID timer fucntion id to large, something wrong now, crash!"); + abort(); + } + function_id_++; + function_maps_[function_id_] = func; + if (timeOut < 1) { + timeOut = 1; + } + LOG_WEEX_BINDING("WeexBindingUtils setNativeTimeout timeOut :%d , type:%d", timeOut, func->GetType()); + + TimerTask *task = new TimerTask(this->id.c_str(), function_id_, + timeOut, interval); + if (this->getObjectType() == WeexInstance){ + task ->from_instance_ = true; + } else { + task->from_instance_ = false; + } + timeQueue->addTimerTask(task); + return task->taskId; +} + +void WeexGlobalObjectV2::clearNativeTimeout(int timer_task_id) { + LOG_WEEX_BINDING("[WeexBindingUtils] method :clearNativeTimeout"); + if (nullptr == timeQueue) { + return; + } + timeQueue->removeTimer(timer_task_id); +} + + diff --git a/weex_core/Source/js_runtime/weex/object/weex_global_object_v2.h b/weex_core/Source/js_runtime/weex/object/weex_global_object_v2.h new file mode 100644 index 0000000000..305786e90d --- /dev/null +++ b/weex_core/Source/js_runtime/weex/object/weex_global_object_v2.h @@ -0,0 +1,96 @@ +/** + * 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 陈佩翰 on 2019/2/22. +// + +#ifndef PROJECT_WEEX_GLOBAL_OBJECT_V2_H +#define PROJECT_WEEX_GLOBAL_OBJECT_V2_H + + +#include "core/bridge/script_bridge.h" +#include "include/WeexApiHeader.h" +//#include "task/timer_queue.h" +#include "js_runtime/weex/task/timer_queue.h" +#include "js_runtime/runtime/runtime_context.h" +#include "js_runtime/runtime/runtime_object.h" + + +enum WeexGlobalObjectType { + WeexInstance, + WeexGlobal, + AppWorker +}; + + +class WeexGlobalObjectV2 { +public: + std::vector m_initFrameworkParams; + std::string id = ""; + TimerQueue *timeQueue = nullptr; + std::unique_ptr context; + std::unique_ptr global_object_binding; + +private: + WeexCore::ScriptBridge *script_bridge_; + WeexGlobalObjectType object_type_; + uint32_t function_id_; + std::map function_maps_; + + +public: + + void makeWeexInstanceObject(unicorn::RuntimeVM *vm, const std::string &id, const std::string &name); + + void makeWeexGlobalObject(unicorn::RuntimeVM *vm); + + void makeAppWorkerObject(unicorn::RuntimeVM *vm); + + + void addExtraOptions(std::vector ¶ms); + + void initWxEnvironment(std::vector ¶ms, bool isSave); + + inline WeexCore::ScriptBridge *js_bridge() { return script_bridge_; } + + void setScriptBridge(WeexCore::ScriptBridge *script_bridge); + + + unicorn::RuntimeValues *removeTimer(uint32_t function_id); + + + int setNativeTimeout(unicorn::RuntimeValues *func, int timeOut, bool interval); + void clearNativeTimeout(int timer_task_id); + + unicorn::RuntimeValues *getTimerFunction(uint32_t function_id); + + void updateInitFrameworkParams(const std::string& key, const std::string& value); + + inline WeexGlobalObjectType getObjectType() { + return this->object_type_; + } + +private: + // uint32_t genFunctionID(); + + //void addTimer(uint32_t function_id, unicorn::RuntimeValues *func); +}; + + +#endif //PROJECT_WEEX_GLOBAL_OBJECT_V2_H diff --git a/weex_core/Source/js_runtime/weex/object/weex_object_holder_v2.cpp b/weex_core/Source/js_runtime/weex/object/weex_object_holder_v2.cpp new file mode 100644 index 0000000000..96abb3544b --- /dev/null +++ b/weex_core/Source/js_runtime/weex/object/weex_object_holder_v2.cpp @@ -0,0 +1,63 @@ +/** + * 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 陈佩翰 on 2019/2/22. +// + +#include "weex_object_holder_v2.h" +#include "js_runtime/utils/log_utils.h" + +WeexObjectHolderV2::WeexObjectHolderV2(unicorn::RuntimeVM *vm, TimerQueue *timeQueue, + bool isMultiProgress) { + this->vm = vm; + this->timeQueue = timeQueue; + this->isMultiProgress = isMultiProgress; +} + +void WeexObjectHolderV2::initFromParams(std::vector ¶ms, bool forAppContext) { + if (forAppContext) { + LOG_RUNTIME("Create MiniApp worker Context"); + globalObject = std::unique_ptr(this->createAppWorkerObject()); + } else { + LOG_RUNTIME("Create global Context"); + globalObject = std::unique_ptr(this->createWeexObject()); + } + globalObject->timeQueue = this->timeQueue; + globalObject->initWxEnvironment(params, true); +} + +WeexGlobalObjectV2 *WeexObjectHolderV2::createWeexObject() { + auto weex_object = new WeexGlobalObjectV2(); + weex_object->makeWeexGlobalObject(this->vm); + return weex_object; +} + +WeexGlobalObjectV2 *WeexObjectHolderV2::createInstancecObject(const std::string &id, const std::string &name) { + auto weex_object = new WeexGlobalObjectV2(); + weex_object->makeWeexInstanceObject(this->vm, id, name); + weex_object->initWxEnvironment(globalObject.get()->m_initFrameworkParams, false); + return weex_object; +} + +WeexGlobalObjectV2 *WeexObjectHolderV2::createAppWorkerObject() { + auto app_work_object = new WeexGlobalObjectV2(); + app_work_object->makeAppWorkerObject(this->vm); + return app_work_object; +} + diff --git a/weex_core/Source/js_runtime/weex/object/weex_object_holder_v2.h b/weex_core/Source/js_runtime/weex/object/weex_object_holder_v2.h new file mode 100644 index 0000000000..b262e73d15 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/object/weex_object_holder_v2.h @@ -0,0 +1,57 @@ +/** + * 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 陈佩翰 on 2019/2/22. +// + +#ifndef PROJECT_WEEX_OBJECT_HOLDER_V2_H +#define PROJECT_WEEX_OBJECT_HOLDER_V2_H + +#include +#include +#include "js_runtime/weex/task/timer_queue.h" +#include "weex_global_object_v2.h" + + +class WeexObjectHolderV2 { +public: + std::unique_ptr globalObject; + + std::map m_jsInstanceGlobalObjectMap; + + explicit WeexObjectHolderV2(unicorn::RuntimeVM *vm, TimerQueue *timeQueue, bool isMultiProgress); + + void initFromParams(std::vector ¶ms, bool forAppContext); + + WeexGlobalObjectV2 *createWeexObject(); + + WeexGlobalObjectV2 *createInstancecObject(const std::string &id, const std::string &name); + + WeexGlobalObjectV2 *createAppWorkerObject(); + + TimerQueue *timeQueue; + +private: + bool isMultiProgress; + unicorn::RuntimeVM *vm; + +}; + + +#endif //PROJECT_WEEX_OBJECT_HOLDER_V2_H diff --git a/weex_core/Source/js_runtime/weex/object/weex_runtime.h b/weex_core/Source/js_runtime/weex/object/weex_runtime.h new file mode 100644 index 0000000000..6ece2c234b --- /dev/null +++ b/weex_core/Source/js_runtime/weex/object/weex_runtime.h @@ -0,0 +1,105 @@ +/** + * 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 董亚运 on 2019/3/25. +// +#ifndef WEEXV8_WEEX_RUNTIME_VIR +#define WEEXV8_WEEX_RUNTIME_VIR +#include "core/bridge/script_bridge.h" +#include "js_runtime/weex/object/weex_object_holder_v2.h" + +class WeexRuntime { + public: + + explicit WeexRuntime(WeexCore::ScriptBridge* scriptBridge) { this->script_bridge_ = scriptBridge;} + + WeexCore::ScriptBridge* script_bridge_; + + virtual bool hasInstanceId(std::string &id) = 0; + + + virtual int initFramework(const std::string &script, + std::vector ¶ms) = 0; + + + virtual int + initAppFramework(const std::string &instanceId, const std::string &appFramework, + std::vector ¶ms) = 0; + + virtual int createAppContext(const std::string &instanceId, const std::string &jsBundle) = 0; + + virtual std::unique_ptr exeJSOnAppWithResult(const std::string &instanceId, + const std::string &jsBundle) = 0; + + virtual int + callJSOnAppContext(const std::string &instanceId, + const std::string &func, + std::vector ¶ms) = 0; + + virtual int destroyAppContext(const std::string &instanceId) = 0; + + virtual int exeJsService(const std::string &source) = 0; + + virtual int exeCTimeCallback(const std::string &source) = 0; + + + virtual int + exeJS(const std::string &instanceId, const std::string &nameSpace, const std::string &func, + std::vector ¶ms) = 0; + + + virtual std::unique_ptr exeJSWithResult(const std::string &instanceId, + const std::string &nameSpace, + const std::string &func, + std::vector ¶ms) = 0; + + virtual void exeJSWithCallback(const std::string &instanceId, + const std::string &nameSpace, + const std::string &func, + std::vector ¶ms, + long callback_id) = 0; + + virtual int createInstance(const std::string &instanceId, + const std::string &func, + const std::string &script, + const std::string &opts, + const std::string &initData, + const std::string &extendsApi, + std::vector ¶ms) = 0; + + virtual std::unique_ptr exeJSOnInstance(const std::string &instanceId, + const std::string &script) = 0; + + virtual int UpdateInitFrameworkParams(const std::string& key, const std::string& value, const std::string& desc)=0; + + virtual int destroyInstance(const std::string &instanceId) = 0; + + + virtual int updateGlobalConfig(const std::string &config) = 0; + + virtual int exeTimerFunctionForRunTimeApi(const std::string &instanceId, + uint32_t timerFunction, + bool is_from_instance) = 0; + + virtual void removeTimerFunctionForRunTimeApi(const std::string &instanceId, + const uint32_t timerFunction, + bool is_from_instance) = 0; +}; + +#endif //WEEXV8_WEEX_RUNTIME_VIR \ No newline at end of file diff --git a/weex_core/Source/js_runtime/weex/object/weex_runtime_v2.cpp b/weex_core/Source/js_runtime/weex/object/weex_runtime_v2.cpp new file mode 100644 index 0000000000..bf28fc4cbb --- /dev/null +++ b/weex_core/Source/js_runtime/weex/object/weex_runtime_v2.cpp @@ -0,0 +1,767 @@ +/** + * 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 陈佩翰 on 2019/2/22. +// + +#include "js_runtime/runtime/js_runtime_conversion.h" +#include "js_runtime/weex/utils/weex_conversion_utils.h" +#include "android/jsengine/object/weex_env.h" +#include "js_runtime/weex/utils/weex_jsc_utils.h" +#include "js_runtime/weex/object/weex_runtime_v2.h" +#include "js_runtime/runtime/runtime_vm.h" +#include "core/bridge/script_bridge.h" +#include "js_runtime/runtime/engine_context.h" +#include "js_runtime/utils/log_utils.h" + +WeexRuntimeV2::WeexRuntimeV2(TimerQueue *timeQueue, WeexCore::ScriptBridge *script_bridge, bool isMultiProgress) + : WeexRuntime(script_bridge) { + LOGE("jsengine","use runtime"); + WeexEnv::getEnv()->initJSC(isMultiProgress); + WeexEnv::getEnv()->jsc_init_finished(); + WeexEnv::getEnv()->locker()->signal(); + //create vm + this->vm_ = new unicorn::RuntimeVM(); + //code + weex_object_holder_v2_.reset(new WeexObjectHolderV2(this->vm_, timeQueue, isMultiProgress)); +} + +bool WeexRuntimeV2::hasInstanceId(std::string &id) { + auto iterator = app_worker_context_holder_map_v2_.find(id); + if (iterator != app_worker_context_holder_map_v2_.end()) { + return true; + } + auto it = weex_object_holder_v2_->m_jsInstanceGlobalObjectMap.find(id); + return it != weex_object_holder_v2_->m_jsInstanceGlobalObjectMap.end(); +} + +int WeexRuntimeV2::initFramework(const std::string &script, + std::vector ¶ms) { + weex_object_holder_v2_->initFromParams(params, false); + return this->_initFrameworkWithScript(script); +} + +int WeexRuntimeV2::initAppFramework(const std::string &instanceId, const std::string &appFramework, + std::vector ¶ms) { + + auto pHolder = getLightAppObjectHolderV2(instanceId); + LOG_RUNTIME("Weex jsserver initAppFramework %s", instanceId); + if (pHolder == nullptr) { + auto holder = + new WeexObjectHolderV2(this->vm_, weex_object_holder_v2_->timeQueue, multi_process_flag_); + holder->initFromParams(params, true); + LOG_RUNTIME("Weex jsserver initAppFramework pHolder == null and id %s", + instanceId); + app_worker_context_holder_map_v2_[std::string(instanceId)] = holder; + } + return _initAppFrameworkWithScript(instanceId, appFramework); +} + +int WeexRuntimeV2::createAppContext(const std::string &instanceId, const std::string &jsBundle) { + + if (instanceId == "") { + return static_cast(false); + } + + std::string pre = ""; + if (instanceId.length() > 6) { + pre = instanceId.substr(0, 7); + } + + std::string get_context_fun_name = ""; + std::string final_instanceId = ""; + if (pre == "plugin_") { + get_context_fun_name = "__get_plugin_context__"; + final_instanceId = instanceId.substr(7, instanceId.length() - 7); + } else { + get_context_fun_name = "__get_app_context__"; + final_instanceId = instanceId; + } + + LOG_RUNTIME("WeexRuntime createAppContext get_context_fun_name = %s", + get_context_fun_name); + + // new a global object + // -------------------------------------------------- + auto appWorkerObjectHolderV2 = getLightAppObjectHolderV2(final_instanceId); + if (appWorkerObjectHolderV2 == nullptr) { + return static_cast(false); + } + + auto worker_globalObject = appWorkerObjectHolderV2->globalObject.get(); + if (worker_globalObject == nullptr) { + LOGE("WeexRuntime createAppContext worker_globalObject is null"); + return static_cast(false); + } + auto app_globalObject = appWorkerObjectHolderV2->createAppWorkerObject(); + app_globalObject->setScriptBridge(script_bridge_); + + + // Create App Context from Worker + std::vector args; + std::string jsException; + JSRunTimeValue funcRet = worker_globalObject->context->GetEngineContext()->callJavaScriptFunc( + nullptr, + std::string(get_context_fun_name), + args, + &jsException + ); + if (nullptr == funcRet) { + LOGE("WeexRuntime: createAppContext failed , exception :%s", jsException.c_str()); + return static_cast(false); + } + LOG_RUNTIME("WeexRuntime: try convert funcRetValue to obj"); + JSRunTimeObject + fucRetJSObject = worker_globalObject->context->GetEngineContext()->toObjectFromValue(funcRet); + if (nullptr == fucRetJSObject) { + LOGE("WeexRuntime: CreateAppContext get funcRet obj failed"); + return static_cast(false); + } + + std::vector nameArray; + + if (!worker_globalObject->context->GetEngineContext()->GetObjectPropertyNameArray(fucRetJSObject, + nameArray)) { + LOGE("WeexRuntime: createAppContext get fucRetJSObject properties name array failed"); + return static_cast(false); + } + + for (const auto &propertyName : nameArray) { + auto propertyValue = + worker_globalObject->context->GetEngineContext()->GetPropertyValueFromObject( + propertyName, fucRetJSObject); + if (nullptr == propertyValue) { + LOGE("WeexRuntime: createAppContext get fucRetJSObject properties value failed, name:%s", + propertyName.c_str()); + return static_cast(false); + } + app_globalObject->context->GetEngineContext()->setObjectValue(nullptr, + propertyName, + propertyValue); + } + + app_globalObject->id = std::string(final_instanceId); + LOG_RUNTIME("WeexRuntime:createAppContext instanceId %s", + final_instanceId); + + if (!jsBundle.empty()) { + std::string exeption; + if (!app_globalObject->context->ExecuteJavaScript(std::string(jsBundle), + &exeption)) { + if (!exeption.empty()) { + app_globalObject->js_bridge()->core_side()->ReportException(instanceId.c_str(), + "createAppContext", + exeption.c_str()); + } + return static_cast(false); + } + } else { + LOGE("WeexRuntime: createAppContext app.js is empty!"); + return static_cast(false); + } + LOG_RUNTIME("WeexRuntime: createAppContext complete!"); + return static_cast(true); +} + +std::unique_ptr WeexRuntimeV2::exeJSOnAppWithResult(const std::string &instanceId, + const std::string &jsBundle) { + LOGE("WeexRuntime: exeJSOnAppWithResult app.js is empty!!!!!!!!!!!, instanceId:%s, jsBundle:%s", + instanceId.c_str(), jsBundle.c_str()); + std::unique_ptr returnResult; + return returnResult; +} + +int WeexRuntimeV2::callJSOnAppContext(const std::string &instanceId, const std::string &func, + std::vector ¶ms) { + if (instanceId == "" || func == "") { + return static_cast(false); + } + std::string runFunc = std::string(func); + LOG_RUNTIME("WeexRuntime callJSOnAppContext func is %s", runFunc.c_str()); + + // Get Worker global object + auto appWorkerHolder = getLightAppObjectHolderV2(instanceId); + if (appWorkerHolder == nullptr) { + return static_cast(false); + } + + auto worker_globalObject = appWorkerHolder->globalObject.get(); + if (worker_globalObject == nullptr) { + return static_cast(false); + } + + std::vector args; + _geJSRuntimeArgsFromWeexParams(worker_globalObject->context->GetEngineContext(), &args, params); + + std::string jsException; + worker_globalObject->context->GetEngineContext()->callJavaScriptFunc( + nullptr, + runFunc, + args, + &jsException + ); + + if (!jsException.empty()) { + worker_globalObject->js_bridge()->core_side()->ReportException(instanceId.c_str(), + func.c_str(), + jsException.c_str()); + LOGE("callJSOnAppContext error on instance %s ,func:%s", + instanceId.c_str(), + runFunc.c_str()); + return static_cast(false); + } + LOG_RUNTIME("WeexRuntime callJSOnAppContext func complete: %s", runFunc.c_str()); + return static_cast(true); +} + +int WeexRuntimeV2::destroyAppContext(const std::string &instanceId) { + auto appWorkerObjectHolder = getLightAppObjectHolderV2(instanceId); + if (appWorkerObjectHolder == nullptr) { + return static_cast(false); + } + + LOG_RUNTIME("Weex jsserver IPCJSMsg::DESTORYAPPCONTEXT end1 %s", instanceId); + std::map::iterator it_find_instance; + auto objectMap = appWorkerObjectHolder->m_jsInstanceGlobalObjectMap; + it_find_instance = objectMap.find(instanceId); + if (it_find_instance != objectMap.end()) { + // LOGE("Weex jsserver IPCJSMsg::DESTORYAPPCONTEXT mAppInstanceGlobalObjectMap donnot contain and return"); + objectMap.erase(instanceId); + } + + if (appWorkerObjectHolder->timeQueue != nullptr) + appWorkerObjectHolder->timeQueue->destroyPageTimer(instanceId); + + app_worker_context_holder_map_v2_.erase(instanceId); + delete appWorkerObjectHolder; + appWorkerObjectHolder = nullptr; + return static_cast(true); +} + +int WeexRuntimeV2::exeJsService(const std::string &source) { + std::string source_str = std::string(source); + + std::string js_exception; + bool succeed = + weex_object_holder_v2_->globalObject->context->ExecuteJavaScript(source_str, &js_exception); + + if (!js_exception.empty()) { + weex_object_holder_v2_->globalObject->js_bridge()->core_side()->ReportException("service", + "exeJsService", + js_exception.c_str()); + } + + if (!succeed) { + LOGE("exec service error :%s ,script: :%s", js_exception.c_str(), source_str.c_str()); + return static_cast(false); + } else { + return static_cast(true); + } +} + +int WeexRuntimeV2::exeCTimeCallback(const std::string &source) { + std::string source_str = std::string(source); + if (!weex_object_holder_v2_->globalObject->context->ExecuteJavaScript(source_str, nullptr)) { + LOGE("jsLog JNI_Error EXECTIMERCALLBACK >>> scriptStr :%s", source_str.c_str()); + return static_cast(false); + } else { + return static_cast(true); + } +} + +int WeexRuntimeV2::exeJS(const std::string &instanceId, const std::string &nameSpace, const std::string &func, + std::vector ¶ms) { + //LOGE("jsengine shopp EXECJS func:%s and params size is %d", func, params.size()); + + std::string runFunc = std::string(func); + std::string instance_id_str = std::string(instanceId); + + WeexGlobalObjectV2 *globalObject = nullptr; + + if (runFunc == "callJS") { + globalObject = weex_object_holder_v2_->m_jsInstanceGlobalObjectMap[instance_id_str]; + if (globalObject == nullptr) { + LOG_RUNTIME("[runtime2]----------->[global] exeJS func:%s", runFunc.c_str()); + globalObject = weex_object_holder_v2_->globalObject.get(); + } else { + runFunc = std::string("__WEEX_CALL_JAVASCRIPT__"); + LOG_RUNTIME("[runtime2]----------->[instance][%s] exeJS func:%s", + instance_id_str.c_str(), + runFunc.c_str()); + } + } else { + globalObject = weex_object_holder_v2_->globalObject.get(); + LOG_RUNTIME("[runtime2]----------->[global] exeJS func:%s", runFunc.c_str()); + } + + std::vector args; + _geJSRuntimeArgsFromWeexParams(globalObject->context->GetEngineContext(), &args, params); + + std::string jsException; + globalObject->context->GetEngineContext()->callJavaScriptFunc( + nullptr, + runFunc, + args, + &jsException + ); + + if (!jsException.empty()) { + globalObject->js_bridge()->core_side()->ReportException(instance_id_str.c_str(), + runFunc.c_str(), + jsException.c_str()); + LOGE("[runtime2]exeJS error on instance %s ,func:%s", instance_id_str.c_str(), runFunc.c_str()); + return static_cast(false); + } + return static_cast(true); +} + +std::unique_ptr +WeexRuntimeV2::exeJSWithResult(const std::string &instanceId, + const std::string &nameSpace, + const std::string &func, + std::vector ¶ms) { + + std::string instance_id_str = std::string(instanceId); + std::string runFunc = std::string(func); + + LOG_RUNTIME("[runtime2]WeexRuntime exeJSWithResult func is %s", runFunc.c_str()); + + std::unique_ptr returnResult; + returnResult.reset(new WeexJSResult); + + // JSGlobalObject *globalObject; + WeexGlobalObjectV2 *globalObject = nullptr; + // fix instanceof Object error + // if function is callJs should us Instance object to call __WEEX_CALL_JAVASCRIPT__ + if (runFunc == "callJS") { + globalObject = weex_object_holder_v2_->m_jsInstanceGlobalObjectMap[instance_id_str]; + if (globalObject == nullptr) { + globalObject = weex_object_holder_v2_->globalObject.get(); + } else { + runFunc = std::string("__WEEX_CALL_JAVASCRIPT__"); + } + } else { + globalObject = weex_object_holder_v2_->globalObject.get(); + } + + std::vector args; + _geJSRuntimeArgsFromWeexParams(globalObject->context->GetEngineContext(), &args, params); + + std::string jsException; + auto values = globalObject->context->GetEngineContext()->CallJavaScriptFuncWithRuntimeValue( + nullptr, + runFunc, + args, + &jsException + ); + + if (!jsException.empty()) { + globalObject->js_bridge()->core_side()->ReportException(instance_id_str.c_str(), + runFunc.c_str(), + jsException.c_str()); + LOGE("[runtime2]exeJS error on instance %s ,func:%s", instance_id_str.c_str(), runFunc.c_str()); + return returnResult; + } + //convert values to returnResult + weex::jsengine::WeexConversionUtils::ConvertRunTimeValueToWeexJSResult(values, + returnResult.get()); + return returnResult; +} + +void WeexRuntimeV2::exeJSWithCallback(const std::string &instanceId, + const std::string &nameSpace, + const std::string &func, + std::vector ¶ms, + long callback_id) { + auto result = exeJSWithResult(instanceId, nameSpace, func, params); + script_bridge_->core_side()->OnReceivedResult(callback_id, result); +} + +int +WeexRuntimeV2::createInstance(const std::string &instanceId, + const std::string &func, + const std::string &script, + const std::string &opts, + const std::string &initData, + const std::string &extendsApi, + std::vector ¶ms) { + + LOG_RUNTIME("WeexRuntime: create createInstance Context"); + + WeexGlobalObjectV2 *impl_globalObject = weex_object_holder_v2_->globalObject.get(); + WeexGlobalObjectV2 *globalObject; + if (instanceId == "") { + LOGE("[runtime2]WeexRuntime: globalObject = impl_globalObject"); + globalObject = impl_globalObject; + } else { + std::string instance_id_str = std::string(instanceId); + auto *temp_object = weex_object_holder_v2_->m_jsInstanceGlobalObjectMap[instance_id_str]; + + if (temp_object == nullptr) { + temp_object = weex_object_holder_v2_->createInstancecObject(instance_id_str, instance_id_str); + temp_object->addExtraOptions(params); + temp_object->id = instance_id_str; + temp_object->setScriptBridge(script_bridge_); + temp_object->timeQueue = weex_object_holder_v2_->timeQueue; + + std::string opts_str = std::string(opts); + std::string init_data_str = std::string(initData); + + std::vector args; + args.push_back(unicorn::RuntimeValues::MakeString(instance_id_str)); + args.push_back(unicorn::RuntimeValues::MakeObjectFromJsonStr(opts_str.c_str())); + args.push_back(unicorn::RuntimeValues::MakeObjectFromJsonStr(init_data_str.c_str())); + std::string jsException; + + auto funcRet = impl_globalObject->context->GetEngineContext()->callJavaScriptFunc( + nullptr, + std::string("createInstanceContext"), + args, + &jsException + ); + + if (!jsException.empty()) { + temp_object->js_bridge()->core_side()->ReportException(instanceId.c_str(), + "run raxApi", + jsException.c_str()); + } + + if (nullptr == funcRet) { + LOGE("WeexRuntime: createInstance failed"); + return static_cast(false); + } + + //1. set vue's prototype to newContext's globalObject prototype + JSRunTimeObject fucRetJSObject = + impl_globalObject->context->GetEngineContext()->toObjectFromValue(funcRet); + if (nullptr == fucRetJSObject) { + LOGE("WeexRuntime: get funcRet obj failed"); + return static_cast(false); + } + + auto vueJSValue = + impl_globalObject->context->GetEngineContext()->GetPropertyValueFromObject("Vue", + fucRetJSObject); + if (nullptr != vueJSValue) { + LOG_RUNTIME("WeexRuntime: try set vue's prototype to newContext's globalObject prototypet"); + auto vueObject = + impl_globalObject->context->GetEngineContext()->toObjectFromValue(vueJSValue); + if (!temp_object->context->GetEngineContext()->SetObjectPrototypeFromValue(vueObject, + nullptr)) { + LOGE( + "WeexRuntime: failed ====> set vue's prototype to newContext's globalObject prototype"); + } + } + + std::vector nameArray; + + if (!impl_globalObject->context->GetEngineContext()->GetObjectPropertyNameArray(fucRetJSObject, + nameArray)) { + LOGE("WeexRuntime: get fucRetJSObject properties name array failed"); + return static_cast(false); + } + + LOG_RUNTIME( + "WeexRuntime: get fucRetJSObject properties name array succeed,globalContext:%p,instance context:%p", + impl_globalObject->context->GetEngineContext()->GetContext(), + temp_object->context->GetEngineContext()->GetContext() + ); + + for (auto propertyName : nameArray) { + auto propertyValue = + impl_globalObject->context->GetEngineContext()->GetPropertyValueFromObject( + propertyName, fucRetJSObject); + if (nullptr == propertyValue) { + LOGE("WeexRuntime: get fucRetJSObject properties value failed, name:%s", + propertyName.c_str()); + return static_cast(false); + } + + temp_object->context->GetEngineContext()->setObjectValue(nullptr, + propertyName, + propertyValue); + } + weex_object_holder_v2_->m_jsInstanceGlobalObjectMap[instance_id_str] = temp_object; + LOG_RUNTIME("create Instance succeed :%s", instance_id_str.c_str()); + } + globalObject = temp_object; + } + + std::string js_exception; + if (!extendsApi.empty()) { + LOGE("[runtime2] run rax api ,length:%d", extendsApi.length()); + if (!globalObject->context->ExecuteJavaScript(std::string(extendsApi), + &js_exception)) { + LOGE("before createInstanceContext run rax api Error :%s", js_exception.c_str()); + if (!js_exception.empty()) { + globalObject->js_bridge()->core_side()->ReportException(instanceId.c_str(), + "run raxApi", + js_exception.c_str()); + } + return static_cast(false); + } + } + + if (!script.empty()) { + if (!globalObject->context->GetEngineContext()->RunJavaScript(std::string(script), + &js_exception)) { + LOGE("createInstanceContext and ExecuteJavaScript Error :%s", js_exception.c_str()); + if (!js_exception.empty()) { + globalObject->js_bridge()->core_side()->ReportException(instanceId.c_str(), + "createInstanceContext", + js_exception.c_str()); + } + return static_cast(false); + } + } + return static_cast(true); +} + +std::unique_ptr WeexRuntimeV2::exeJSOnInstance(const std::string &instanceId, + const std::string &script) { + std::string instance_id_str = std::string(instanceId); + + std::unique_ptr returnResult; + returnResult.reset(new WeexJSResult); + + // JSGlobalObject *globalObject = weexObjectHolder->m_jsInstanceGlobalObjectMap[instanceId]; + WeexGlobalObjectV2 + *globalObject = weex_object_holder_v2_->m_jsInstanceGlobalObjectMap[instance_id_str]; + if (globalObject == nullptr) { + // globalObject = weexObjectHolder->m_globalObject.get(); + globalObject = weex_object_holder_v2_->globalObject.get(); + } + std::string jsException; + auto execResult = + globalObject->context->ExecuteJavaScriptWithResult(std::string(script), + &jsException); + + if (!jsException.empty()) { + LOGE("exec JS on instance %s, exception:%s", instance_id_str.c_str(), jsException.c_str()); + globalObject->js_bridge()->core_side()->ReportException(instance_id_str.c_str(), + "execJSOnInstance", + jsException.c_str()); + return nullptr; + } + // const char *data = returnValue.toWTFString(globalObject->globalExec()); + std::string execResultStr; + execResult.get()->GetAsString(&execResultStr); + const char *data = execResultStr.c_str(); + returnResult->length = strlen(data); + char *buf = new char[returnResult->length + 1]; + strcpy(buf, data); + returnResult->data.reset(buf); + return returnResult; + +} + +int WeexRuntimeV2::destroyInstance(const std::string &instanceId) { + std::string instance_id_str = std::string(instanceId); + // LOGE("IPCJSMsg::DESTORYINSTANCE"); + auto *globalObject = weex_object_holder_v2_->m_jsInstanceGlobalObjectMap[instance_id_str]; + if (globalObject == nullptr) { + return static_cast(true); + } + // LOGE("DestoryInstance map 11 length:%d", weexObjectHolder->m_jsGlobalObjectMap.size()); + weex_object_holder_v2_->m_jsInstanceGlobalObjectMap.erase(instance_id_str); + // LOGE("DestoryInstance map 22 length:%d", weexObjectHolder->m_jsGlobalObjectMap.size()); + if (weex_object_holder_v2_->timeQueue != nullptr) { + weex_object_holder_v2_->timeQueue->destroyPageTimer(instance_id_str.c_str()); + } + // LOGE("[WEEX][release] delete object"); + delete globalObject; + globalObject = nullptr; + return static_cast(true); +} + +int WeexRuntimeV2::updateGlobalConfig(const std::string &config) { + doUpdateGlobalSwitchConfig(config.c_str()); + return static_cast(true); +} + +int WeexRuntimeV2::UpdateInitFrameworkParams(const std::string &key, const std::string &value, + const std::string &desc) { + WeexGlobalObjectV2 * globalObject= weex_object_holder_v2_->globalObject.get(); + globalObject->updateInitFrameworkParams(key,value); + return static_cast(true); +} + +int WeexRuntimeV2::_initFrameworkWithScript(const std::string &source) { + + weex_object_holder_v2_->globalObject->setScriptBridge(script_bridge_); + std::string exception; + + weex_object_holder_v2_->globalObject->context->ExecuteJavaScript(std::string(source), + &exception); + + if (!exception.empty()) { + weex_object_holder_v2_->globalObject->js_bridge()->core_side()->ReportException("jsfm", + "_initFramework", + exception.c_str()); + return false; + } + std::vector args; + auto version = + weex_object_holder_v2_->globalObject->context->GetEngineContext()->callJavaScriptFunc( + nullptr, + std::string("getJSFMVersion"), + args, + &exception + ); + auto versionStr = unicorn::JSRuntimeConversion::JSRunTimeValueToRuntimeValue( + weex_object_holder_v2_->globalObject->context->GetEngineContext(), nullptr, version + ); + + std::string jsfmVersion; + + if (nullptr == versionStr.get() || !versionStr.get()->IsString() + || !versionStr.get()->GetAsString(&jsfmVersion)) { + LOGE("WeexRuntime getJSFMVersion failed ,version:%s, exception: %s", + jsfmVersion.c_str(), + exception.c_str()); + return false; + } + weex_object_holder_v2_->globalObject->js_bridge()->core_side()->SetJSVersion(jsfmVersion.c_str()); + return true; +} + +int WeexRuntimeV2::_initAppFrameworkWithScript(const std::string &instanceId, + const std::string &appFramework) { + LOG_RUNTIME("WeexRuntime _initAppFramework implements %s", instanceId); + auto appWorkerObjectHolder = getLightAppObjectHolderV2(instanceId); + if (appWorkerObjectHolder == nullptr) { + LOGE("WeexRuntime _initAppFramework implements appWorkerHolder is null"); + return static_cast(false); + } + auto worker_globalObject = appWorkerObjectHolder->globalObject.get(); + worker_globalObject->setScriptBridge(script_bridge_); + worker_globalObject->id = std::string(instanceId); + + std::string js_exception; + if (!worker_globalObject->context->ExecuteJavaScript(std::string(appFramework), + &js_exception)) { + if (!js_exception.empty()) { + worker_globalObject->js_bridge()->core_side()->ReportException(instanceId.c_str(), + "initAppFramework", + js_exception.c_str()); + } + LOGE("WeexRuntime run worker failed"); + return static_cast(false); + } + + LOG_RUNTIME("WeexRuntime _initAppFramework implements complete"); + return static_cast(true); +} + +WeexObjectHolderV2 *WeexRuntimeV2::getLightAppObjectHolderV2(const std::string &instanceId) { + auto iterator = app_worker_context_holder_map_v2_.find(instanceId); + if (iterator == app_worker_context_holder_map_v2_.end()) { + return nullptr; + } + return app_worker_context_holder_map_v2_.at(instanceId); +} + +void +WeexRuntimeV2::_geJSRuntimeArgsFromWeexParams(unicorn::EngineContext *context, + std::vector *obj, + std::vector ¶ms) { + for (auto paramsObject : params) { + obj->push_back(weex::jsengine + ::WeexConversionUtils + ::WeexValueToRuntimeValue(context, paramsObject)); + } +} + +int WeexRuntimeV2::exeTimerFunctionForRunTimeApi(const std::string &instanceId, + uint32_t timerFunction, + bool is_from_instance) { + + auto weexObject = findWeexObj(instanceId, is_from_instance); + LOG_WEEX_BINDING("exeTimerFunctionForRunTimeApi :findWeexObj %p", weexObject); + + if (weexObject == nullptr) { + LOGE("exeTimerFunctionForRunTimeApi nullptr == weexObject"); + return 0; + } + auto func = weexObject->getTimerFunction(timerFunction); + LOG_WEEX_BINDING("exeTimerFunctionForRunTimeApi :getTimerFunction %p", func); + std::vector args; + if (nullptr == func) { + LOGE("api: timer callback func is null"); + return 0; + } + + LOG_WEEX_BINDING("exeTimerFunctionForRunTimeApi :before GetAsFunction "); + auto function = func->GetAsFunction(); + LOG_WEEX_BINDING("exeTimerFunctionForRunTimeApi :after GetAsFunction function:%p", function); + auto globalContext = weexObject->context->GetEngineContext(); + LOG_WEEX_BINDING("exeTimerFunctionForRunTimeApi :GetEngineContext %p", globalContext); + auto jsContext = globalContext->GetContext(); + LOG_WEEX_BINDING("exeTimerFunctionForRunTimeApi :jsContext %p", jsContext); + + //function->SetJSContext(static_cast(jsContext)); + //LOG_WEEX_BINDING("run native timer func at instnace :%s, taskId:%d",globalObject->id.c_str(),timerFunction); + + function->Call( + static_cast(jsContext), + 0, + args + ); + LOG_WEEX_BINDING("exeTimerFunctionForRunTimeApi :function->Call"); + return 0; +} + +void WeexRuntimeV2::removeTimerFunctionForRunTimeApi(const std::string &instanceId, + const uint32_t timerFunction, + bool is_from_instance) { + auto weexObject = findWeexObj(instanceId, is_from_instance); + LOG_WEEX_BINDING("removeTimerFunctionForRunTimeApi weexObj:%p", weexObject); + if (nullptr == weexObject) { + LOGE("removeTimerFunctionForRunTimeApi nullptr == weexObject"); + return; + } + LOG_WEEX_BINDING("removeTimerFunctionForRunTimeApi"); + unicorn::RuntimeValues *targetFuncValue = weexObject->removeTimer(timerFunction); + + if (nullptr != targetFuncValue) { + LOG_WEEX_BINDING("before delete fucn ,instance:%s, taskId:%d ,succeed", + instanceId.c_str(), + timerFunction); + delete targetFuncValue; + LOG_WEEX_BINDING("delete fucn ,instance:%s, taskId:%d ,succeed", + instanceId.c_str(), + timerFunction); + targetFuncValue = nullptr; + } +} + +WeexGlobalObjectV2 *WeexRuntimeV2::findWeexObj(const std::string &instanceId, bool is_instance) { + WeexGlobalObjectV2 *weexObject = nullptr; + if (is_instance) { + weexObject = + weex_object_holder_v2_->m_jsInstanceGlobalObjectMap[std::string(instanceId)]; + } else { + auto appWorkerHolder = getLightAppObjectHolderV2(instanceId); + if (appWorkerHolder == nullptr) { + return nullptr; + } + weexObject = appWorkerHolder->globalObject.get(); + } + return weexObject; +} diff --git a/weex_core/Source/js_runtime/weex/object/weex_runtime_v2.h b/weex_core/Source/js_runtime/weex/object/weex_runtime_v2.h new file mode 100644 index 0000000000..f1db62a7f3 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/object/weex_runtime_v2.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. + */ +// +// Created by 陈佩翰 on 2019/2/22. +// + +#ifndef PROJECT_WEEX_RUNTIME_V2_H +#define PROJECT_WEEX_RUNTIME_V2_H + +#include +#include "weex_object_holder_v2.h" +#include "weex_runtime.h" + + +class WeexRuntimeV2 : public WeexRuntime { + +public: + + explicit WeexRuntimeV2(TimerQueue *timeQueue, WeexCore::ScriptBridge *script_bridge, bool isMultiProgress); + + bool hasInstanceId(std::string &id) override; + + + int initFramework(const std::string &script, std::vector ¶ms) override; + + int + initAppFramework(const std::string &instanceId, const std::string &appFramework, + std::vector ¶ms) override; + + int createAppContext(const std::string &instanceId, const std::string &jsBundle) override; + + std::unique_ptr exeJSOnAppWithResult(const std::string &instanceId, const std::string &jsBundle) override; + + + int + callJSOnAppContext(const std::string &instanceId, const std::string &func, std::vector ¶ms) override; + + int destroyAppContext(const std::string &instanceId) override; + + int exeJsService(const std::string &source) override; + + int exeCTimeCallback(const std::string &source) override; + + + int + exeJS(const std::string &instanceId, const std::string &nameSpace, const std::string &func, + std::vector ¶ms) override; + + + std::unique_ptr exeJSWithResult(const std::string &instanceId, const std::string &nameSpace, const std::string &func, + std::vector ¶ms) override; + + void exeJSWithCallback(const std::string &instanceId, const std::string &nameSpace, const std::string &func, + std::vector ¶ms, long callback_id) override; + + int createInstance(const std::string &instanceId, const std::string &func, const std::string &script, const std::string &opts, + const std::string &initData, const std::string &extendsApi, + std::vector ¶ms) override; + + std::unique_ptr exeJSOnInstance(const std::string &instanceId, const std::string &script) override; + + int destroyInstance(const std::string &instanceId) override; + + int updateGlobalConfig(const std::string &config) override; + + int UpdateInitFrameworkParams(const std::string& key, const std::string& value, const std::string& desc); + + WeexObjectHolderV2 *getLightAppObjectHolderV2(const std::string &instanceId); + + int exeTimerFunctionForRunTimeApi(const std::string &instanceId, uint32_t timerFunction, bool is_from_instance) override; + + void removeTimerFunctionForRunTimeApi(const std::string &instanceId,const uint32_t timerFunction, bool is_from_instance) override; + + +protected: + int _initFrameworkWithScript(const std::string &source); + + int _initAppFrameworkWithScript(const std::string &instanceId, const std::string &appFramework); + + void _geJSRuntimeArgsFromWeexParams(unicorn::EngineContext *context, std::vector *obj, + std::vector ¶ms); + + WeexGlobalObjectV2* findWeexObj(const std::string &instanceId, bool is_instance); + + +protected: + std::unique_ptr weex_object_holder_v2_; + std::map app_worker_context_holder_map_v2_; + unicorn::RuntimeVM *vm_; + bool multi_process_flag_; +}; + + +#endif //PROJECT_WEEX_RUNTIME_V2_H diff --git a/weex_core/Source/js_runtime/weex/task/back_to_weex_core_queue.cpp b/weex_core/Source/js_runtime/weex/task/back_to_weex_core_queue.cpp new file mode 100644 index 0000000000..4ca57c4409 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/back_to_weex_core_queue.cpp @@ -0,0 +1,155 @@ +/** + * 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 董亚运 on 2019/1/8. +// + +#include "base/android/log_utils.h" +#include "android/jsengine/object/weex_env.h" +#include "back_to_weex_core_queue.h" +#include "third_party/IPC/Buffering/IPCBuffer.h" + + +static void *startThread(void *td) { + auto *self = static_cast(td); + WeexEnv::getEnv()->initIPC(); + self->isInitOk = true; + self->start(); + return NULL; +} + +int BackToWeexCoreQueue::addTask(BackToWeexCoreQueue::IPCTask *task) { + threadLocker.lock(); + taskQueue_.push_back(task); + int size = taskQueue_.size(); + threadLocker.unlock(); + threadLocker.signal(); + return size; +} + +void BackToWeexCoreQueue::init() { + pthread_t thread; + pthread_create(&thread, nullptr, startThread, this); + pthread_setname_np(thread, "BackToWeexCoreQueue"); +} + +void BackToWeexCoreQueue::start() { + while (!m_stop) { + BackToWeexCoreQueue::IPCTask *task = getTask(); + if (task == nullptr) { + continue; + } + task->run(); + delete task; + } + +} + +BackToWeexCoreQueue::IPCTask *BackToWeexCoreQueue::getTask() { + BackToWeexCoreQueue::IPCTask *task = nullptr; + while (task == nullptr) { + threadLocker.lock(); + while (taskQueue_.empty() || !isInitOk) { + threadLocker.wait(); + } + + if (taskQueue_.empty()) { + threadLocker.unlock(); + continue; + } + + assert(!taskQueue_.empty()); + task = taskQueue_.front(); + taskQueue_.pop_front(); + threadLocker.unlock(); + } + + return task; +} + +void BackToWeexCoreQueue::stop() { + m_stop = true; +} + +void BackToWeexCoreQueue::IPCTask::run() { + if (params.empty()) + return; + + std::unique_ptr serializer(createIPCSerializer());; + serializer->setMsg(static_cast(this->m_type)); + std::vector::iterator it; + it = params.begin(); + while (it != params.end()) { + IPCArgs *&reference = *it; + serializer->add(reference->m_str, reference->m_length); + delete reference; + it++; + } + + std::unique_ptr buffer = serializer->finish(); + std::unique_ptr result = WeexEnv::getEnv()->m_ipc_client_->getSender()->send( + buffer.get()); + if (m_future != nullptr) { + m_future->setResult(result); + } +} + +void BackToWeexCoreQueue::IPCTask::addParams(const char *str, size_t len) { + IPCArgs *x = new BackToWeexCoreQueue::IPCArgs(str, len); + this->params.push_back(x); +} + +void BackToWeexCoreQueue::IPCTask::set_future(BackToWeexCoreQueue::Future *m_feature) { + IPCTask::m_future = m_feature; +} + +BackToWeexCoreQueue::IPCTask::~IPCTask() { +} + + +void BackToWeexCoreQueue::Future::setResult(std::unique_ptr &result) { + thread_locker_.lock(); + has_result_ = true; + result_ = std::move(result); + thread_locker_.unlock(); + thread_locker_.signal(); +} + +std::unique_ptr BackToWeexCoreQueue::Future::waitResult() { + thread_locker_.lock(); + while (!has_result_) { + thread_locker_.wait(); + } + thread_locker_.unlock(); + return std::move(result_); +} + +BackToWeexCoreQueue::IPCArgs::IPCArgs(const char *str, size_t len) { + char *ret = nullptr; + size_t strLen = 0; + if (str != nullptr) { + strLen = len == 0 ? strlen(str) : len; + ret = new char[strLen + 1]; + memcpy(ret, str, static_cast(strLen)); + ret[strLen] = '\0'; + + } + this->m_str = ret; + this->m_length = strLen; +} diff --git a/weex_core/Source/js_runtime/weex/task/back_to_weex_core_queue.h b/weex_core/Source/js_runtime/weex/task/back_to_weex_core_queue.h new file mode 100644 index 0000000000..ef808cd0e8 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/back_to_weex_core_queue.h @@ -0,0 +1,118 @@ +/** + * 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 董亚运 on 2019/1/8. +// + +#ifndef WEEX_PROJECT_BACK_TO_WEEX_CORE_QUEUE_H +#define WEEX_PROJECT_BACK_TO_WEEX_CORE_QUEUE_H + + +#include +#include +#include +#include +#include +#include "base/utils/ThreadLocker.h" +#include "base/closure.h" + +class BackToWeexCoreQueue { + +public: + + class Future { + + public: + + Future() : has_result_(false) {} + + ~Future() {} + + void setResult(std::unique_ptr &result); + + std::unique_ptr waitResult(); + + private: + bool has_result_ = false; + std::unique_ptr result_; + ThreadLocker thread_locker_; + }; + + class IPCArgs { + + public: + explicit IPCArgs(const char *str, size_t len = 0); + + ~IPCArgs() { + if (m_str != nullptr) + delete (m_str); + m_length = 0; + } + + public: + char *m_str; + size_t m_length; + }; + + class IPCTask { + public: + std::vector params; + + explicit IPCTask(IPCProxyMsg type) : m_type(type), + m_future(nullptr) {} + + ~IPCTask(); + + void run(); + + void addParams(const char *str, size_t len = 0); + + void set_future(Future *m_feature); + + private: + IPCProxyMsg m_type; + Future *m_future; + + }; + + explicit BackToWeexCoreQueue(): + m_stop(false) {}; + + BackToWeexCoreQueue::IPCTask *getTask(); + + void start(); + + void stop(); + + void init(); + + int addTask(BackToWeexCoreQueue::IPCTask *task); + + +private: + std::deque taskQueue_; + ThreadLocker threadLocker; + bool m_stop; + +public: + volatile bool isInitOk = false; +}; + + +#endif //WEEX_PROJECT_BACK_TO_WEEX_CORE_QUEUE_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/call_js_on_app_context_task.cpp b/weex_core/Source/js_runtime/weex/task/impl/call_js_on_app_context_task.cpp new file mode 100644 index 0000000000..c12cd16bc7 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/call_js_on_app_context_task.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 Darin on 20/07/2018. +// + +#include "call_js_on_app_context_task.h" + +CallJsOnAppContextTask::CallJsOnAppContextTask(const std::string &instanceId, const std::string &func, + std::vector ¶ms) : WeexTask(instanceId) { + + this->func = func; + + exeJsArgs = new ExeJsArgs(params); + +} + +CallJsOnAppContextTask::CallJsOnAppContextTask(const std::string &instanceId, const std::string &func, IPCArguments *arguments, + size_t startCount) : WeexTask(instanceId) { + + this->func = func; + + exeJsArgs = new ExeJsArgs(arguments, startCount); + +} + +void CallJsOnAppContextTask::run(WeexRuntime *runtime) { + runtime->callJSOnAppContext(instanceId, func, exeJsArgs->params); +} diff --git a/weex_core/Source/js_runtime/weex/task/impl/call_js_on_app_context_task.h b/weex_core/Source/js_runtime/weex/task/impl/call_js_on_app_context_task.h new file mode 100644 index 0000000000..e6ea6231c0 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/call_js_on_app_context_task.h @@ -0,0 +1,51 @@ +/** + * 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 20/07/2018. +// + +#ifndef WEEXV8_CALLJSONAPPCONTEXTTASK_H +#define WEEXV8_CALLJSONAPPCONTEXTTASK_H + + +#include "js_runtime/weex/task/weex_task.h" +#include "android/jsengine/object/args/exe_js_args.h" + +class CallJsOnAppContextTask : public WeexTask { + +public: + CallJsOnAppContextTask(const std::string &instanceId, const std::string &func, std::vector ¶ms); + + CallJsOnAppContextTask(const std::string &instanceId, const std::string &func, IPCArguments *arguments, size_t startCount); + + void run(WeexRuntime *runtime) override; + std::string taskName() override { return " CallJsOnAppContextTask "; } + + + ~CallJsOnAppContextTask() { + delete exeJsArgs; + } + +private: + std::string func; + ExeJsArgs *exeJsArgs; +}; + + +#endif //WEEXV8_CALLJSONAPPCONTEXTTASK_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/create_app_context_task.cpp b/weex_core/Source/js_runtime/weex/task/impl/create_app_context_task.cpp new file mode 100644 index 0000000000..d33e4ff905 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/create_app_context_task.cpp @@ -0,0 +1,31 @@ +/** + * 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 20/07/2018. +// + +#include "create_app_context_task.h" + +CreateAppContextTask::CreateAppContextTask(const std::string &instanceId, const std::string &script) : WeexTask(instanceId) { + this->script = script; +} + +void CreateAppContextTask::run(WeexRuntime *runtime) { + runtime->createAppContext(instanceId, script); +} diff --git a/weex_core/Source/js_runtime/weex/task/impl/create_app_context_task.h b/weex_core/Source/js_runtime/weex/task/impl/create_app_context_task.h new file mode 100644 index 0000000000..3a165c90e5 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/create_app_context_task.h @@ -0,0 +1,41 @@ +/** + * 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 20/07/2018. +// + +#ifndef WEEXV8_CREATEAPPCONTEXTTASK_H +#define WEEXV8_CREATEAPPCONTEXTTASK_H + + +#include "js_runtime/weex/task/weex_task.h" + +class CreateAppContextTask : public WeexTask { +public: + CreateAppContextTask(const std::string &instanceId, const std::string &script); + + void run(WeexRuntime *runtime) override; + std::string taskName() override { return " CreateAppContextTask "; } + +private: + std::string script; +}; + + +#endif //WEEXV8_CREATEAPPCONTEXTTASK_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/create_instance_task.cpp b/weex_core/Source/js_runtime/weex/task/impl/create_instance_task.cpp new file mode 100644 index 0000000000..47ef7f2e93 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/create_instance_task.cpp @@ -0,0 +1,41 @@ +/** + * 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 20/07/2018. +// + +#include "create_instance_task.h" + +void CreateInstanceTask::addExtraArg(std::string arg) { + extraArgs.push_back(arg); +} + +CreateInstanceTask::CreateInstanceTask(const std::string &instanceId, const std::string &script, std::vector& params) : WeexTask(instanceId) { + this->script = script; + initExtraArgs.reset(new InitFrameworkArgs(params)); +} + +void CreateInstanceTask::run(WeexRuntime *runtime) { + if (extraArgs.size() < 4) + return; + + runtime->createInstance(instanceId, extraArgs.at(0), this->script, extraArgs.at(1), extraArgs.at(2), + extraArgs.at(3), initExtraArgs->params); +} + diff --git a/weex_core/Source/js_runtime/weex/task/impl/create_instance_task.h b/weex_core/Source/js_runtime/weex/task/impl/create_instance_task.h new file mode 100644 index 0000000000..4f825d7ce4 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/create_instance_task.h @@ -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 Darin on 20/07/2018. +// + +#ifndef WEEXV8_CREATEINSTANCETASK_H +#define WEEXV8_CREATEINSTANCETASK_H + +#include "android/jsengine/object/args/init_framework_args.h" +#include "js_runtime/weex/task/weex_task.h" + +class CreateInstanceTask : public WeexTask { +public: + CreateInstanceTask(const std::string &instanceId, const std::string &script, std::vector& params); + + void addExtraArg(std::string arg); + + void run(WeexRuntime *runtime) override ; + std::string taskName() override { return "CreateInstanceTask"; } + +private: + std::vector extraArgs; + std::unique_ptr initExtraArgs; + std::string script; +}; + + +#endif //WEEXV8_CREATEINSTANCETASK_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/ctime_callback_task.cpp b/weex_core/Source/js_runtime/weex/task/impl/ctime_callback_task.cpp new file mode 100644 index 0000000000..6b495c4c3f --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/ctime_callback_task.cpp @@ -0,0 +1,29 @@ +/** + * 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 20/07/2018. +// + +#include "ctime_callback_task.h" + +CTimeCallBackTask::CTimeCallBackTask(const std::string &script) : WeexTask("") {} + +void CTimeCallBackTask::run(WeexRuntime *runtime) { + runtime->exeCTimeCallback(script); +} diff --git a/weex_core/Source/js_runtime/weex/task/impl/ctime_callback_task.h b/weex_core/Source/js_runtime/weex/task/impl/ctime_callback_task.h new file mode 100644 index 0000000000..5128037e5c --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/ctime_callback_task.h @@ -0,0 +1,42 @@ +/** + * 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 20/07/2018. +// + +#ifndef WEEXV8_CTIMECALLBACKTASK_H +#define WEEXV8_CTIMECALLBACKTASK_H + + +#include "js_runtime/weex/task/weex_task.h" + +class CTimeCallBackTask :public WeexTask{ +public: + CTimeCallBackTask(const std::string &script); + + void run(WeexRuntime *runtime) override; + std::string taskName() override { return "CTimeCallBackTask"; } + +private: + std::string script; + +}; + + +#endif //WEEXV8_CTIMECALLBACKTASK_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/destory_app_context_task.cpp b/weex_core/Source/js_runtime/weex/task/impl/destory_app_context_task.cpp new file mode 100644 index 0000000000..68a7057874 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/destory_app_context_task.cpp @@ -0,0 +1,29 @@ +/** + * 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 20/07/2018. +// + +#include "destory_app_context_task.h" + +DestoryAppContextTask::DestoryAppContextTask(const std::string &instanceId) : WeexTask(instanceId) {} + +void DestoryAppContextTask::run(WeexRuntime *runtime) { + runtime->destroyAppContext(instanceId); +} diff --git a/weex_core/Source/js_runtime/weex/task/impl/destory_app_context_task.h b/weex_core/Source/js_runtime/weex/task/impl/destory_app_context_task.h new file mode 100644 index 0000000000..1768a06b4a --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/destory_app_context_task.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. + */ +// +// Created by Darin on 20/07/2018. +// + +#ifndef WEEXV8_DESTORYAPPCONTEXTTASK_H +#define WEEXV8_DESTORYAPPCONTEXTTASK_H + + +#include "js_runtime/weex/task/weex_task.h" + +class DestoryAppContextTask: public WeexTask { +public: + DestoryAppContextTask(const std::string &instanceId); + + void run(WeexRuntime *runtime) override; + std::string taskName() override { return "DestoryAppContextTask"; } + +}; + + +#endif //WEEXV8_DESTORYAPPCONTEXTTASK_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/destory_instance_task.cpp b/weex_core/Source/js_runtime/weex/task/impl/destory_instance_task.cpp new file mode 100644 index 0000000000..bc76cf2b88 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/destory_instance_task.cpp @@ -0,0 +1,29 @@ +/** + * 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 20/07/2018. +// + +#include "destory_instance_task.h" + +DestoryInstanceTask::DestoryInstanceTask(const std::string &instanceId) : WeexTask(instanceId) {} + +void DestoryInstanceTask::run(WeexRuntime *runtime) { + runtime->destroyInstance(instanceId); +} diff --git a/weex_core/Source/js_runtime/weex/task/impl/destory_instance_task.h b/weex_core/Source/js_runtime/weex/task/impl/destory_instance_task.h new file mode 100644 index 0000000000..d9b9bb39ff --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/destory_instance_task.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. + */ +// +// Created by Darin on 20/07/2018. +// + +#ifndef WEEXV8_DESTORYINSTANCETASK_H +#define WEEXV8_DESTORYINSTANCETASK_H + + +#include "js_runtime/weex/task/weex_task.h" + +class DestoryInstanceTask :public WeexTask { +public: + explicit DestoryInstanceTask(const std::string &instanceId); + + + void run(WeexRuntime *runtime) override; + std::string taskName() override { return " DestoryInstanceTask "; } +}; + + +#endif //WEEXV8_DESTORYINSTANCETASK_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/exe_js_on_app_with_result.cpp b/weex_core/Source/js_runtime/weex/task/impl/exe_js_on_app_with_result.cpp new file mode 100644 index 0000000000..e6ef020657 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/exe_js_on_app_with_result.cpp @@ -0,0 +1,35 @@ +/** + * 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 20/07/2018. +// + +#include "exe_js_on_app_with_result.h" + +ExeJsOnAppWithResultTask::ExeJsOnAppWithResultTask(const std::string &instanceId, const std::string &script) : WeexTask( + instanceId) { + this->script = script; +} + +void ExeJsOnAppWithResultTask::run(WeexRuntime *runtime) { + auto ptr = runtime->exeJSOnAppWithResult(instanceId, script); + if (future() != nullptr) { + future()->setResult(ptr); + } +} diff --git a/weex_core/Source/js_runtime/weex/task/impl/exe_js_on_app_with_result.h b/weex_core/Source/js_runtime/weex/task/impl/exe_js_on_app_with_result.h new file mode 100644 index 0000000000..bebb7a6238 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/exe_js_on_app_with_result.h @@ -0,0 +1,43 @@ +/** + * 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 20/07/2018. +// + +#ifndef WEEXV8_EXEJSONAPPWITHRESULTTASK_H +#define WEEXV8_EXEJSONAPPWITHRESULTTASK_H + + +#include "js_runtime/weex/task/weex_task.h" + +class ExeJsOnAppWithResultTask : public WeexTask { +public: + ExeJsOnAppWithResultTask(const std::string &instanceId, const std::string &script); + + + void run(WeexRuntime *runtime) override; + std::string taskName() override { return "ExeJsOnAppWithResultTask"; } + +private: + std::string script; + +}; + + +#endif //WEEXV8_EXEJSONAPPWITHRESULTTASK_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/exe_js_on_instance_task.cpp b/weex_core/Source/js_runtime/weex/task/impl/exe_js_on_instance_task.cpp new file mode 100644 index 0000000000..f8d2ea6fcf --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/exe_js_on_instance_task.cpp @@ -0,0 +1,35 @@ +/** + * 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 20/07/2018. +// + +#include "exe_js_on_instance_task.h" + +ExeJsOnInstanceTask::ExeJsOnInstanceTask(const std::string &instanceId, const std::string &script) : WeexTask( + instanceId) { + this->script = script; +} + +void ExeJsOnInstanceTask::run(WeexRuntime *runtime) { + std::unique_ptr ptr = runtime->exeJSOnInstance(instanceId, script); + if (future() != nullptr) { + future()->setResult(ptr); + } +} diff --git a/weex_core/Source/js_runtime/weex/task/impl/exe_js_on_instance_task.h b/weex_core/Source/js_runtime/weex/task/impl/exe_js_on_instance_task.h new file mode 100644 index 0000000000..3d757d326e --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/exe_js_on_instance_task.h @@ -0,0 +1,41 @@ +/** + * 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 20/07/2018. +// + +#ifndef WEEXV8_EXEJSONINSTANCETASK_H +#define WEEXV8_EXEJSONINSTANCETASK_H + + +#include "js_runtime/weex/task/weex_task.h" + +class ExeJsOnInstanceTask: public WeexTask { +public: + explicit ExeJsOnInstanceTask(const std::string &instanceId, const std::string &script); + + void run(WeexRuntime *runtime) override; + std::string taskName() override { return "ExeJsOnInstanceTask"; } + +private: + std::string script; +}; + + +#endif //WEEXV8_EXEJSONINSTANCETASK_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/exe_js_services_task.cpp b/weex_core/Source/js_runtime/weex/task/impl/exe_js_services_task.cpp new file mode 100644 index 0000000000..22d6a80775 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/exe_js_services_task.cpp @@ -0,0 +1,31 @@ +/** + * 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 20/07/2018. +// + +#include "exe_js_services_task.h" + +ExeJsServicesTask::ExeJsServicesTask(const std::string &script) : WeexTask("") { + this->script = script; +} + +void ExeJsServicesTask::run(WeexRuntime *runtime) { + runtime->exeJsService(this->script); +} diff --git a/weex_core/Source/js_runtime/weex/task/impl/exe_js_services_task.h b/weex_core/Source/js_runtime/weex/task/impl/exe_js_services_task.h new file mode 100644 index 0000000000..629c079c09 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/exe_js_services_task.h @@ -0,0 +1,42 @@ +/** + * 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 20/07/2018. +// + +#ifndef WEEXV8_EXEJSSERVICESTASK_H +#define WEEXV8_EXEJSSERVICESTASK_H + + +#include "js_runtime/weex/task/weex_task.h" + +class ExeJsServicesTask :public WeexTask { +public: + explicit ExeJsServicesTask(const std::string &script); + + void run(WeexRuntime *runtime) override ; + std::string taskName() override { return " ExeJsServicesTask"; } + +private: + std::string script; + +}; + + +#endif //WEEXV8_EXEJSSERVICESTASK_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/exe_js_task.cpp b/weex_core/Source/js_runtime/weex/task/impl/exe_js_task.cpp new file mode 100644 index 0000000000..be5c0e3e97 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/exe_js_task.cpp @@ -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. + */ +// +// Created by Darin on 20/07/2018. +// + +#include "exe_js_task.h" +#include "js_runtime/weex/object/weex_runtime.h" + +void ExeJsTask::run(WeexRuntime *runtime) { + if (extraArgs.size() < 2) + return; + + if (callbackId >= 0) { + runtime->exeJSWithCallback(instanceId, extraArgs.at(0), extraArgs.at(1), + exeJsArgs->params, callbackId); + } else if (!withResult) { + runtime->exeJS(instanceId, extraArgs.at(0), extraArgs.at(1), exeJsArgs->params); + } else { + std::unique_ptr jsResult = runtime->exeJSWithResult(instanceId, extraArgs.at(0), extraArgs.at(1), + exeJsArgs->params); + + if (future() != nullptr) { + future()->setResult(jsResult); + } + } +} + +void ExeJsTask::addExtraArg(std::string arg) { + this->extraArgs.push_back(arg); +} + +ExeJsTask::ExeJsTask(const std::string &instanceId, std::vector ¶ms, bool withResult) : WeexTask( + instanceId) { + this->withResult = withResult; + callbackId = -1; + exeJsArgs = new ExeJsArgs(params); +} + +ExeJsTask::ExeJsTask(const std::string &instanceId, std::vector ¶ms, long callback_id) : WeexTask( + instanceId) { + this->withResult = true; + callbackId = callback_id; + exeJsArgs = new ExeJsArgs(params); +} + +ExeJsTask::~ExeJsTask() { + delete exeJsArgs; +} + +ExeJsTask *ExeJsTask::clone() { + auto *task = new ExeJsTask(instanceId, this->exeJsArgs->params); + for (const auto &extraArg : this->extraArgs) { + task->addExtraArg(extraArg); + } + return task; +} diff --git a/weex_core/Source/js_runtime/weex/task/impl/exe_js_task.h b/weex_core/Source/js_runtime/weex/task/impl/exe_js_task.h new file mode 100644 index 0000000000..266fa4d701 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/exe_js_task.h @@ -0,0 +1,52 @@ +/** + * 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 20/07/2018. +// + +#ifndef WEEXV8_EXEJSTASK_H +#define WEEXV8_EXEJSTASK_H + +#include "js_runtime/weex/task/weex_task.h" +#include "android/jsengine/object/args/exe_js_args.h" + +class ExeJsTask : public WeexTask { +public: + ExeJsTask(const std::string &instanceId, std::vector ¶ms, bool withResult = false); + ExeJsTask(const std::string &instanceId, std::vector ¶ms, long callback_id); + void addExtraArg(std::string arg); + + + void run(WeexRuntime *runtime) override; + std::string taskName() override { return "ExeJsTask"; } + + ExeJsTask * clone(); + + ~ExeJsTask() override; + +private: + + bool withResult; + long callbackId; + ExeJsArgs *exeJsArgs; + std::vector extraArgs; +}; + + +#endif //WEEXV8_EXEJSTASK_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/init_framework_task.cpp b/weex_core/Source/js_runtime/weex/task/impl/init_framework_task.cpp new file mode 100644 index 0000000000..a19680b784 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/init_framework_task.cpp @@ -0,0 +1,49 @@ +/** + * 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 20/07/2018. +// + +#include "init_framework_task.h" + +void InitFrameworkTask::run(WeexRuntime *runtime) { + if (instanceId.empty()) + runtime->initFramework(script, args->params); + else + runtime->initAppFramework(instanceId, script, args->params); +} + +InitFrameworkTask::InitFrameworkTask(const std::string &script, std::vector ¶ms) + : InitFrameworkTask("", script, params) { + +} + +InitFrameworkTask::InitFrameworkTask(const std::string &instanceId, const std::string &script, + std::vector ¶ms) : WeexTask(instanceId) { + + this->script = script; + args = new InitFrameworkArgs(params); +} + +InitFrameworkTask::~InitFrameworkTask() { + delete args; +} +InitFrameworkTask *InitFrameworkTask::clone() { + return new InitFrameworkTask(this->script, args->params); +} diff --git a/weex_core/Source/js_runtime/weex/task/impl/init_framework_task.h b/weex_core/Source/js_runtime/weex/task/impl/init_framework_task.h new file mode 100644 index 0000000000..e1f4cd9457 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/init_framework_task.h @@ -0,0 +1,53 @@ +/** + * 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 20/07/2018. +// + +#ifndef WEEXV8_INITFRAMEWORKTASK_H +#define WEEXV8_INITFRAMEWORKTASK_H + + +#include "js_runtime/weex/task/weex_task.h" +#include "android/jsengine/object/args/init_framework_args.h" + +class InitFrameworkTask : public WeexTask { +public: + + + explicit InitFrameworkTask(const std::string &instanceId, const std::string &script, + std::vector ¶ms); + + explicit InitFrameworkTask(const std::string &script, std::vector ¶ms); + + void run(WeexRuntime *runtime) override; + + std::string taskName() override { return "InitFrameworkTask"; } + + InitFrameworkTask *clone(); + + ~InitFrameworkTask(); + +private: + InitFrameworkArgs *args; + std::string script; +}; + + +#endif //WEEXV8_INITFRAMEWORKTASK_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/native_timer_task.cpp b/weex_core/Source/js_runtime/weex/task/impl/native_timer_task.cpp new file mode 100644 index 0000000000..cb52d73d8d --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/native_timer_task.cpp @@ -0,0 +1,41 @@ +/** + * 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 20/07/2018. +// + +#include "native_timer_task.h" +#include "android/jsengine/object/weex_env.h" +#include "js_runtime/weex/object/weex_runtime.h" + +NativeTimerTask::NativeTimerTask(const std::string &instanceId, + uint32_t function, + int taskId, + bool one_shot) + : WeexTask(instanceId, taskId) { + this->timerFunction = function; + repeatTimer = !one_shot; +} + +void NativeTimerTask::run(WeexRuntime *runtime) { + runtime->exeTimerFunctionForRunTimeApi(instanceId, timerFunction, is_from_instance); + if (!repeatTimer) + runtime->removeTimerFunctionForRunTimeApi(instanceId, timerFunction, is_from_instance); + +} diff --git a/weex_core/Source/js_runtime/weex/task/impl/native_timer_task.h b/weex_core/Source/js_runtime/weex/task/impl/native_timer_task.h new file mode 100644 index 0000000000..c0df7ede8c --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/native_timer_task.h @@ -0,0 +1,43 @@ +/** + * 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 20/07/2018. +// + +#ifndef WEEXV8_NATIVE_TIMERTASK_H +#define WEEXV8_NATIVE_TIMERTASK_H + +#include "js_runtime/weex/task/weex_task.h" + +class NativeTimerTask : public WeexTask { +public: + explicit NativeTimerTask(const std::string &instanceId, uint32_t function, int taskId, bool one_shot); + ~NativeTimerTask() override {} + + void run(WeexRuntime *runtime) override; + std::string taskName() override { return "NativeTimerTask"; } + uint32_t timerFunctionID() const { return timerFunction; } + +private: + uint32_t timerFunction; + bool repeatTimer; +}; + + +#endif //WEEXV8_TIMERTASK_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/take_heap_snapshot.cpp b/weex_core/Source/js_runtime/weex/task/impl/take_heap_snapshot.cpp new file mode 100644 index 0000000000..3dab516204 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/take_heap_snapshot.cpp @@ -0,0 +1,28 @@ +/** + * 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 20/07/2018. +// + +#include "take_heap_snapshot.h" + +TakeHeapSnapShot::TakeHeapSnapShot(const std::string &instanceId) : WeexTask(instanceId) {} + +void TakeHeapSnapShot::run(WeexRuntime *runtime) { +} diff --git a/weex_core/Source/js_runtime/weex/task/impl/take_heap_snapshot.h b/weex_core/Source/js_runtime/weex/task/impl/take_heap_snapshot.h new file mode 100644 index 0000000000..0b4ad371ea --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/take_heap_snapshot.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. + */ +// +// Created by Darin on 20/07/2018. +// + +#ifndef WEEXV8_TAKEHEAPSNAPSHOT_H +#define WEEXV8_TAKEHEAPSNAPSHOT_H + + +#include "js_runtime/weex/task/weex_task.h" + +class TakeHeapSnapShot : public WeexTask { +public: + TakeHeapSnapShot(const std::string &instanceId); + + void run(WeexRuntime *runtime) override ; + +}; + + +#endif //WEEXV8_TAKEHEAPSNAPSHOT_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/update_global_config_task.cpp b/weex_core/Source/js_runtime/weex/task/impl/update_global_config_task.cpp new file mode 100644 index 0000000000..f7043596d4 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/update_global_config_task.cpp @@ -0,0 +1,31 @@ +/** + * 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 20/07/2018. +// + +#include "update_global_config_task.h" + +UpdateGlobalConfigTask::UpdateGlobalConfigTask(const std::string &script) : WeexTask("") { + this->script = script; +} + +void UpdateGlobalConfigTask::run(WeexRuntime *runtime) { + runtime->updateGlobalConfig(script); +} diff --git a/weex_core/Source/js_runtime/weex/task/impl/update_global_config_task.h b/weex_core/Source/js_runtime/weex/task/impl/update_global_config_task.h new file mode 100644 index 0000000000..89ed0692f0 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/update_global_config_task.h @@ -0,0 +1,43 @@ +/** + * 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 20/07/2018. +// + +#ifndef WEEXV8_UPDATEGLOBALCONFIGTASK_H +#define WEEXV8_UPDATEGLOBALCONFIGTASK_H + + +#include "js_runtime/weex/task/weex_task.h" + +class UpdateGlobalConfigTask: public WeexTask { +public: + UpdateGlobalConfigTask(const std::string &script); + + void run(WeexRuntime *runtime) override; + + std::string taskName() override { return "UpdateGlobalConfigTask"; } + +private: + std::string script; + +}; + + +#endif //WEEXV8_UPDATEGLOBALCONFIGTASK_H diff --git a/weex_core/Source/js_runtime/weex/task/impl/update_init_framework_params_task.cpp b/weex_core/Source/js_runtime/weex/task/impl/update_init_framework_params_task.cpp new file mode 100644 index 0000000000..643985e776 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/update_init_framework_params_task.cpp @@ -0,0 +1,36 @@ +/** + * 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 furture on 2019/3/25. +// + +#include "update_init_framework_params_task.h" + + +UpdateInitFrameworkParamsTask::UpdateInitFrameworkParamsTask(const std::string &key, + const std::string &value, + const std::string &desc): WeexTask("") { + this->key_ = key; + this->value_ = value; + this->desc_ = desc; +} + +void UpdateInitFrameworkParamsTask::run(WeexRuntime *runtime) { + runtime->UpdateInitFrameworkParams(key_, value_, desc_); +} \ No newline at end of file diff --git a/weex_core/Source/js_runtime/weex/task/impl/update_init_framework_params_task.h b/weex_core/Source/js_runtime/weex/task/impl/update_init_framework_params_task.h new file mode 100644 index 0000000000..549c47e3fb --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/impl/update_init_framework_params_task.h @@ -0,0 +1,46 @@ +/** + * 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 furture on 2019/3/25. +// + +#ifndef WEEX_PROJECT_UPDATEINITFRAMEWORKPARAMSTASK_H +#define WEEX_PROJECT_UPDATEINITFRAMEWORKPARAMSTASK_H + +#include "js_runtime/weex/task/weex_task.h" + + +class UpdateInitFrameworkParamsTask : public WeexTask { + +public: + UpdateInitFrameworkParamsTask(const std::string& key, const std::string& value, const std::string& desc); + + void run(WeexRuntime *runtime) override; + + std::string taskName() override { return "UpdateInitFrameworkParamsTask"; } + +private: + std::string key_; + std::string value_; + std::string desc_; + +}; + + +#endif //WEEX_PROJECT_UPDATEINITFRAMEWORKPARAMSTASK_H diff --git a/weex_core/Source/js_runtime/weex/task/timer_queue.cpp b/weex_core/Source/js_runtime/weex/task/timer_queue.cpp new file mode 100644 index 0000000000..45e5f301e7 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/timer_queue.cpp @@ -0,0 +1,205 @@ +/** + * 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 12/06/2018. +// + +#include "timer_queue.h" +//#include "android/jsengine/task/weex_task_queue.h" +#include "weex_task_queue.h" +#include "android/jsengine/object/weex_env.h" +//#include "android/jsengine/weex_runtime.h" +#include "js_runtime/weex/object/weex_runtime.h" + +static void *startThread(void *td) { + auto *self = static_cast(td); + self->start(); + return NULL; +} + +void TimerQueue::init() { + + if (this->isInit) + return; + + this->isInit = true; + + pthread_t thread; + pthread_create(&thread, nullptr, startThread, this); + pthread_setname_np(thread, "TimerQueueThread"); +} + +void TimerQueue::start() { + while (true) { + auto pTask = getTask(); + LOGE("getTask return task"); + bool ptaskHasGlobalObject; + ptaskHasGlobalObject = weexTaskQueue->weexRuntime->hasInstanceId(pTask->instanceID); + //LOGE("[weex-task]getTask return task,ptaskHasGlobalObject :%d ",ptaskHasGlobalObject); + + if (ptaskHasGlobalObject && weexTaskQueue->weexRuntime->hasInstanceId(pTask->instanceID)) { + // LOGE("[weex-task]before add to weexTaskQueue"); + weexTaskQueue->addTimerTask(pTask->instanceID, + pTask->m_function, + pTask->taskId, + !pTask->repeat, + pTask->from_instance_); + //LOGE("[weex-task]end add to weexTaskQueue"); + if (pTask->repeat && ptaskHasGlobalObject + && weexTaskQueue->weexRuntime->hasInstanceId(pTask->instanceID)) { + LOGE("repreat"); + addTimerTask(new TimerTask(pTask)); + } + } + delete (pTask); + pTask = nullptr; + } +} + +TimerQueue::TimerQueue(WeexTaskQueue *taskQueue) { + nextTaskWhen = 0; + this->weexTaskQueue = taskQueue; + init(); +} + +int TimerQueue::addTimerTask(TimerTask *timerTask) { + threadLocker.lock(); + auto size = timerQueue_.size(); + if (timerQueue_.empty()) { + timerQueue_.push_back(timerTask); + } else { + auto begin = timerQueue_.begin(); + int i = 0; + for (; i < size; ++i) { + auto it = timerQueue_[i]; + if (timerTask->when < it->when) { + timerQueue_.insert(begin + i, timerTask); + break; + } else if (i == size - 1) { + timerQueue_.push_back(timerTask); + break; + } + } + } + + size = timerQueue_.size(); + if (size > 0) { + nextTaskWhen = timerQueue_.front()->when; + } + threadLocker.unlock(); + threadLocker.signal(); + return size; +} + +//对比时间 +TimerTask *TimerQueue::getTask() { + TimerTask *task = nullptr; + while (task == nullptr) { + threadLocker.lock(); + while (timerQueue_.empty() || microTime() < nextTaskWhen) { + if (timerQueue_.empty()) { + threadLocker.wait(); + } else { + auto i = threadLocker.waitTimeout(nextTaskWhen); + if (i == ETIMEDOUT) { + break; + } + } + } + + if (timerQueue_.empty()) { + threadLocker.unlock(); + continue; + } + assert(!taskQueue_.empty()); + TimerTask *header = timerQueue_.front(); + nextTaskWhen = header->when; + if (microTime() > nextTaskWhen) { + timerQueue_.pop_front(); + task = header; + } else { + threadLocker.unlock(); + continue; + } + threadLocker.unlock(); + } + return task; +} + +void TimerQueue::removeTimer(int timerId) { + threadLocker.lock(); + if (timerQueue_.empty()) { + threadLocker.unlock(); + return; + } else { + for (auto it = timerQueue_.begin(); it < timerQueue_.end(); ++it) { + auto reference = *it; + if (reference->taskId == timerId) { + timerQueue_.erase(it); + weexTaskQueue->removeTimer(reference->taskId); + if (weexTaskQueue->weexRuntime) { + weexTaskQueue->weexRuntime->removeTimerFunctionForRunTimeApi(reference->instanceID, + reference->m_function, + reference->from_instance_); + } + + delete (reference); + reference = nullptr; + } + } + } + + int size = timerQueue_.size(); + if (size > 0) { + nextTaskWhen = timerQueue_.front()->when; + } + threadLocker.unlock(); + threadLocker.signal(); +} + +void TimerQueue::destroyPageTimer(std::string instanceId) { + threadLocker.lock(); + if (timerQueue_.empty()) { + threadLocker.unlock(); + return; + } else { + for (std::deque::iterator it = timerQueue_.begin(); it < timerQueue_.end(); ++it) { + auto reference = *it; + if (reference->instanceID == instanceId) { + timerQueue_.erase(it); + weexTaskQueue->removeTimer(reference->taskId); + if (weexTaskQueue->weexRuntime) { + weexTaskQueue->weexRuntime->removeTimerFunctionForRunTimeApi(reference->instanceID, + reference->m_function, + reference->from_instance_); + } + + delete (reference); + reference = nullptr; + } + } + } + + int size = timerQueue_.size(); + if (size > 0) { + nextTaskWhen = timerQueue_.front()->when; + } + threadLocker.unlock(); + threadLocker.signal(); +} diff --git a/weex_core/Source/js_runtime/weex/task/timer_queue.h b/weex_core/Source/js_runtime/weex/task/timer_queue.h new file mode 100644 index 0000000000..1f1fd90556 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/timer_queue.h @@ -0,0 +1,63 @@ +/** + * 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 12/06/2018. +// + +#ifndef WEEXV8_TIMERQUEUE_H +#define WEEXV8_TIMERQUEUE_H + +#include +#include + +//#include "android/jsengine/task/timer_task.h" +#include "js_runtime/weex/task/timer_task.h" +#include "base/utils/ThreadLocker.h" + +class TimerTask; +class WeexTaskQueue; + +class TimerQueue { + +public: + void init(); + + void destroyPageTimer(std::string instanceId); + + void removeTimer(int timerId); + + int addTimerTask(TimerTask *timerTask); + + TimerTask *getTask(); + + void start(); + + bool isInit = false; + + explicit TimerQueue(WeexTaskQueue *taskQueue); + +private: + uint64_t nextTaskWhen; + WeexTaskQueue *weexTaskQueue; + std::deque timerQueue_; + ThreadLocker threadLocker; +}; + + +#endif //WEEXV8_TIMERQUEUE_H diff --git a/weex_core/Source/js_runtime/weex/task/timer_task.cpp b/weex_core/Source/js_runtime/weex/task/timer_task.cpp new file mode 100644 index 0000000000..6e71e6a1d6 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/timer_task.cpp @@ -0,0 +1,56 @@ +/** + * 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 12/06/2018. +// + +#include "timer_task.h" +#include "js_runtime/weex/utils/weex_jsc_utils.h" + +TimerTask::TimerTask(const std::string &id, uint32_t function, uint64_t millSecTimeout, bool repeat) { + this->taskId = genTaskId(); + this->instanceID = id; + this->m_function = function; + this->timeout = millSecTimeout; + this->when = microTime() + millSecTimeout * TIMESPCE; + this->repeat = repeat; + // this->global_object_ = global_object; +} + +TimerTask::TimerTask(TimerTask *timerTask) { + this->taskId = timerTask->taskId; + this->instanceID = timerTask->instanceID; + this->repeat = timerTask->repeat; + this->timeout = timerTask->timeout; + this->m_function = timerTask->m_function; + this->when = microTime() + timerTask->timeout * TIMESPCE; + // this->global_object_ = timerTask->global_object_; + this->from_instance_ = timerTask->from_instance_; +} + +TimerTask::TimerTask(TimerTask &timerTask) { + this->taskId = timerTask.taskId; + this->instanceID = timerTask.instanceID; + this->repeat = timerTask.repeat; + this->timeout = timerTask.timeout; + this->m_function = timerTask.m_function; + this->when = microTime() + timerTask.timeout * TIMESPCE; + // this->global_object_ = timerTask.global_object_; + this->from_instance_ = timerTask.from_instance_; +} diff --git a/weex_core/Source/js_runtime/weex/task/timer_task.h b/weex_core/Source/js_runtime/weex/task/timer_task.h new file mode 100644 index 0000000000..5f1cc87e3d --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/timer_task.h @@ -0,0 +1,55 @@ +/** + * 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 12/06/2018. +// + +#ifndef WEEXV8_TIMERTASK_H +#define WEEXV8_TIMERTASK_H + + +#include +#include +class TimerTask { + +public: + int taskId; + + std::string instanceID; + uint32_t m_function; + + uint64_t timeout; + uint64_t when; + + bool repeat = false; + + bool from_instance_ = true; + + // WeexGlobalObject* global_object_; + + explicit TimerTask(const std::string &id, uint32_t function, uint64_t millSecTimeout, bool repeat = false); + + explicit TimerTask(TimerTask *timerTask); + + TimerTask(TimerTask &timerTask); + +}; + + +#endif //WEEXV8_TIMERTASK_H diff --git a/weex_core/Source/js_runtime/weex/task/weex_task.cpp b/weex_core/Source/js_runtime/weex/task/weex_task.cpp new file mode 100644 index 0000000000..00af766ced --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/weex_task.cpp @@ -0,0 +1,41 @@ +/** + * 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 20/07/2018. +// + +#include +#include "weex_task.h" +#include "js_runtime/weex/utils/weex_jsc_utils.h" +void WeexTask::Future::setResult(std::unique_ptr &result) { + thread_locker_.lock(); + has_result_ = true; + result_ = std::move(result); + thread_locker_.unlock(); + thread_locker_.signal(); +} + +std::unique_ptr WeexTask::Future::waitResult() { + thread_locker_.lock(); + while (!has_result_) { + thread_locker_.wait(); + } + thread_locker_.unlock(); + return std::move(result_); +} diff --git a/weex_core/Source/js_runtime/weex/task/weex_task.h b/weex_core/Source/js_runtime/weex/task/weex_task.h new file mode 100644 index 0000000000..3057668690 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/weex_task.h @@ -0,0 +1,85 @@ +/** + * 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 20/07/2018. +// + +#ifndef WEEXV8_WEEXTASK_H +#define WEEXV8_WEEXTASK_H + +#include "base/time_calculator.h" +#include "base/utils/ThreadLocker.h" +#include "js_runtime/weex/utils/weex_jsc_utils.h" +#include "js_runtime/weex/object/weex_runtime_v2.h" +//#include "android/jsengine/weex_runtime.h" + +class WeexTask { + +public: + + class Future { + + public: + + Future() : has_result_(false) {} + + ~Future() {} + + void setResult(std::unique_ptr &result); + + std::unique_ptr waitResult(); + + private: + bool has_result_ = false; + std::unique_ptr result_; + ThreadLocker thread_locker_; + }; + + std::string instanceId; + int taskId; + explicit WeexTask(const std::string &instanceId, int taskId) : future_(nullptr) { + this->instanceId = instanceId; + this->taskId = taskId; + this->timeCalculator = new weex::base::TimeCalculator(weex::base::TaskPlatform::JSS_ENGINE, "", this->instanceId); + }; + + explicit WeexTask(const std::string &instanceId) : WeexTask(instanceId, genTaskId()) {}; + + virtual ~WeexTask() {if(timeCalculator != nullptr) delete timeCalculator;}; + + virtual void run(WeexRuntime *runtime) = 0; + virtual std::string taskName() = 0; + + inline void set_future(Future* future) { + future_ = future; + } + + inline Future* future() { + return future_; + } + + weex::base::TimeCalculator *timeCalculator; + + bool is_from_instance = true; +private: + Future* future_; +}; + + +#endif //WEEXV8_WEEXTASK_H diff --git a/weex_core/Source/js_runtime/weex/task/weex_task_queue.cpp b/weex_core/Source/js_runtime/weex/task/weex_task_queue.cpp new file mode 100644 index 0000000000..332ef26631 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/weex_task_queue.cpp @@ -0,0 +1,186 @@ +/** + * 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 23/05/2018. +// + +#include "weex_task_queue.h" + +#include +#include "js_runtime/weex/task/impl/native_timer_task.h" +#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/object/weex_env.h" +#include "js_runtime/weex/object/weex_runtime_v2.h" + +void WeexTaskQueue::run(WeexTask *task) { + if(task == nullptr || WeexEnv::getEnv()->is_app_crashed()) { + return; + } + task->timeCalculator->set_task_name(task->taskName()); + task->timeCalculator->taskStart(); + task->run(weexRuntime); + task->timeCalculator->taskEnd(); + delete task; +} + + +WeexTaskQueue::~WeexTaskQueue() { + delete this->weexRuntime; + weexRuntime = nullptr; +} + +int WeexTaskQueue::addTask(WeexTask *task) { + return _addTask(task, false); +} + + +WeexTask *WeexTaskQueue::getTask() { + WeexTask *task = nullptr; + while (task == nullptr) { + threadLocker.lock(); + while (taskQueue_.empty() || !isInitOk) { + threadLocker.wait(); + } + + if (taskQueue_.empty()) { + threadLocker.unlock(); + continue; + } + + if(WeexEnv::getEnv()->is_app_crashed()) { + threadLocker.unlock(); + return nullptr; + } + + assert(!taskQueue_.empty()); + task = taskQueue_.front(); + taskQueue_.pop_front(); + threadLocker.unlock(); + } + + return task; +} + +int WeexTaskQueue::addTimerTask(const std::string &id, uint32_t function, int taskId, bool one_shot, bool is_from_instance) { + //LOGE("[weex-binding ]addTimerTask on ==> taskquene %d",taskId); + WeexTask *task = new NativeTimerTask(id, function,taskId, one_shot); + //task->set_global_object(global_object); + task->is_from_instance = is_from_instance; + return _addTask( + task, + false); +} + +void WeexTaskQueue::removeTimer(int taskId) { + threadLocker.lock(); + if (taskQueue_.empty()) { + threadLocker.unlock(); + return; + } else { + for (std::deque::iterator it = taskQueue_.begin(); it < taskQueue_.end(); ++it) { + auto reference = *it; + if (reference->taskId == taskId) { + NativeTimerTask* timer_task = static_cast(reference); + taskQueue_.erase(it); + delete (timer_task); + } + } + } + threadLocker.unlock(); + threadLocker.signal(); +} + +void WeexTaskQueue::start() { + while (true) { + auto pTask = getTask(); + if (pTask == nullptr) + continue; + run(pTask); + } +} + + +static void *startThread(void *td) { + auto *self = static_cast(td); + self->isInitOk = true; + + if (self->weexRuntime == nullptr) { + LOGE("[weex_plan] new runtime"); + self->weexRuntime = new WeexRuntimeV2(new TimerQueue(self),WeexEnv::getEnv()->scriptBridge(), self->isMultiProgress); + + // init IpcClient in Js Thread +// if (self->isMultiProgress) { +// auto *client = new WeexIPCClient(WeexEnv::getEnv()->getIpcClientFd()); +// static_cast(weex::bridge::js::ScriptBridgeInMultiProcess::Instance()->core_side())->set_ipc_client( +// client); +// } + } + + auto pTask = self->getTask(); + self->run(pTask); + self->start(); + return NULL; +} + +void WeexTaskQueue::init() { + pthread_t thread; + LOGE("start weex queue init"); + pthread_create(&thread, nullptr, startThread, this); + pthread_setname_np(thread, "WeexTaskQueueThread"); +} + +int WeexTaskQueue::_addTask(WeexTask *task, bool front) { + threadLocker.lock(); + if (front) { + taskQueue_.push_front(task); + } else { + taskQueue_.push_back(task); + } + + int size = taskQueue_.size(); + threadLocker.unlock(); + threadLocker.signal(); + return size; +} + +WeexTaskQueue::WeexTaskQueue(bool isMultiProgress) : weexRuntime(nullptr) { + this->isMultiProgress = isMultiProgress; + this->weexRuntime = nullptr; +} + +void WeexTaskQueue::removeAllTask(const std::string &id) { + threadLocker.lock(); + if (taskQueue_.empty()) { + threadLocker.unlock(); + return; + } else { + for (std::deque::iterator it = taskQueue_.begin(); it < taskQueue_.end(); ++it) { + auto reference = *it; + if (reference->instanceId == id) { + taskQueue_.erase(it); + delete (reference); + reference = nullptr; + } + } + } + threadLocker.unlock(); + threadLocker.signal(); +} + diff --git a/weex_core/Source/js_runtime/weex/task/weex_task_queue.h b/weex_core/Source/js_runtime/weex/task/weex_task_queue.h new file mode 100644 index 0000000000..fbd4c6cfe3 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/task/weex_task_queue.h @@ -0,0 +1,65 @@ +/** + * 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 23/05/2018. +// + +#ifndef WEEXV8_WEEXTASKQUEUE_H +#define WEEXV8_WEEXTASKQUEUE_H + + +#include +#include "js_runtime/weex/task/weex_task.h" + +class WeexTaskQueue { + +public: + ~WeexTaskQueue(); + explicit WeexTaskQueue(bool isMultiProgress = true); + void run(WeexTask *task); + + int addTask(WeexTask *task); + + WeexTask *getTask(); + + void removeTimer(int taskId); + + void removeAllTask(const std::string &id); + + int addTimerTask(const std::string &id, uint32_t function, int taskId, bool one_shot, bool is_from_instance); + + void start(); + + void init(); + + bool isInitOk = false; + +public: + WeexRuntime *weexRuntime; + bool isMultiProgress; + +private: + int _addTask(WeexTask *task, bool front); + + std::deque taskQueue_; + ThreadLocker threadLocker; +}; + + +#endif //WEEXV8_WEEXTASKQUEUE_H diff --git a/weex_core/Source/js_runtime/weex/utils/weex_conversion_utils.cpp b/weex_core/Source/js_runtime/weex/utils/weex_conversion_utils.cpp new file mode 100644 index 0000000000..04a1cccf2a --- /dev/null +++ b/weex_core/Source/js_runtime/weex/utils/weex_conversion_utils.cpp @@ -0,0 +1,382 @@ +/** + * 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 陈佩翰 on 2019/2/12. +// + +#include +#include "weex_jsc_utils.h" +#include "weex_conversion_utils.h" +#include "js_runtime/utils/log_utils.h" +#include "wson_for_runtime.h" +#include "android/jsengine/object/weex_env.h" + +namespace weex { + namespace jsengine { + +// json11::Json WeexConversionUtils::convertElementToJSon(const Element *element) { +// json11::Json::object styles; +// json11::Json::object attributes; +// json11::Json::array events; +// +// for (auto attrItem:element->attributes) { +// attributes.insert({attrItem.first, attrItem.second}); +// } +// +// for (auto styleItem:element->style) { +// if (styleItem.second->type == style_type_string) { +// styles.insert({styleItem.first, styleItem.second->data.string_value}); +// } else if (styleItem.second->type == style_type_string) { +// styles.insert({styleItem.first, styleItem.second->data.int_value}); +// } else if (styleItem.second->type == style_type_double) { +// styles.insert({styleItem.first, styleItem.second->data.double_value}); +// } else { +// LOGE("[WeexConversionUtils] unsupport style type %d for key:%s", styleItem.second->type, +// styleItem.first.c_str()); +// } +// } +// +// for (auto eventLisener: element->mEventListenList) { +// events.push_back(json11::Json(eventLisener->type)); +// } +// +// json11::Json::array children; +// +// for (auto childNode:element->childNodes) { +// if (childNode->nodeType != childNode->ELEMENT_NODE) { +// LOG_TEST("[DomUtils] convert child element exception, child is not a element ! node ref:%s", +// childNode->ref.c_str()); +// continue; +// } +// auto childElement = static_cast(childNode); +// children.push_back(WeexConversionUtils::convertElementToJSon(childElement)); +// } +// +// json11::Json elementJson = json11::Json::object{ +// {"ref", element->ref.c_str()}, +// {"type", element->localName.c_str()}, +// {"attr", attributes}, +// {"style", styles}, +// {"event", events}, +// {"children", children} +// }; +// +// return elementJson; +// } + +// bool WeexConversionUtils::convertStyleToJSon(const std::string &name, StyleVale *value, std::string &result) { +// json11::Json data; +// if (value->type == style_type_string) { +// data = json11::Json::object{ +// {name, value->data.string_value} +// }; +// +// } else if (value->type == style_type_int) { +// data = json11::Json::object{ +// {name, value->data.int_value} +// }; +// } else if (value->type == style_type_double) { +// data = json11::Json::object{ +// {name, value->data.double_value} +// }; +// } else { +// return false; +// } +// data.dump(result); +// return true; +// } + + bool + WeexConversionUtils::convertKVToJSon(const std::string &name, const ::std::string &value, std::string &result) { + json11::Json data = json11::Json::object{ + {name, value} + }; + data.dump(result); + return true; + } + + json11::Json WeexConversionUtils::RunTimeValuesOfObjectToJson(unicorn::RuntimeValues *vars) { + if (nullptr == vars || vars->IsNull() || vars->IsUndefined()) { + LOG_CONVERSION("arg is not object, json return null json str"); + return json11::Json(nullptr); + } + + if (vars->IsInt()) { + int value; + vars->GetAsInteger(&value); + return json11::Json(value); + } else if (vars->IsDouble()) { + double value; + vars->GetAsDouble(&value); + return json11::Json(value); + } else if (vars->IsBool()) { + bool value; + vars->GetAsBoolean(&value); + return json11::Json(value); + } else if (vars->IsString()) { + std::string value; + vars->GetAsString(&value); + return json11::Json(value); + } else if (vars->IsMap()) { + auto map = vars->GetAsMap()->GetMap(); + json11::Json::object mapJson; + for (auto item : map) { + mapJson.insert({item.first, WeexConversionUtils::RunTimeValuesOfObjectToJson(item.second)}); + } + return mapJson; + } else if (vars->IsArray()) { + json11::Json::array arrayJson; + auto array = vars->GetAsArray()->GetArray(); + for (auto item: array) { + arrayJson.push_back(WeexConversionUtils::RunTimeValuesOfObjectToJson(item)); + } + return arrayJson; + } else { + LOGE("unknow parser json type:%d", vars->GetType()); + return json11::Json(nullptr); + } + } + + unicorn::ScopeValues + WeexConversionUtils::WeexValueToRuntimeValue(unicorn::EngineContext *context, VALUE_WITH_TYPE *paramsObject) { + // LOGE("WeexRuntime: WeexValueToRuntimeValue type is %d", paramsObject->type); + switch (paramsObject->type) { + case ParamsType::DOUBLE: { + LOG_CONVERSION("WeexValueToRuntimeValue double :%d", paramsObject->value.doubleValue); + return unicorn::RuntimeValues::MakeDouble(paramsObject->value.doubleValue); + } + case ParamsType::STRING: { + WeexString *ipcstr = paramsObject->value.string; + // LOG_CONVERSION("WeexValueToRuntimeValue string :%s", string2String.utf8().data()); + return unicorn::RuntimeValues::MakeString(weexString2String(ipcstr)); + } + case ParamsType::JSONSTRING: { + const WeexString *ipcJsonStr = paramsObject->value.string; + auto res = unicorn::RuntimeValues::MakeObjectFromJsonStr(weexString2String(ipcJsonStr)); + LOG_CONVERSION("WeexValueToRuntimeValue JSONSTRING succeed"); + return res; + } + case ParamsType::BYTEARRAY: { + // LOG_TEST("WeexValueToRuntimeValue BYTEARRAY"); + //tips: close wson case + // const WeexByteArray *array = paramsObject->value.byteArray; + // JSValue o = wson::toJSValue(state, (void *) array->content, array->length); + +// obj->append(o); + // obj->push_back(unicorn::RuntimeValues::MakeObjectFromWson(static_cast(array->content),array->length)); + // LOG_TEST("WeexValueToRuntimeValue wson bbyte array"); + LOG_CONVERSION("WeexValueToRuntimeValue wson"); + const WeexByteArray *array = paramsObject->value.byteArray; + return wson::toRunTimeValueFromWson(context, (void *) array->content, array->length); + } + default: + LOGE("WeexValueToRuntimeValue unkonw value type :%d",paramsObject->type); + return unicorn::RuntimeValues::MakeUndefined(); + } + } + + void WeexConversionUtils::ConvertRunTimeVaueToWson(unicorn::RuntimeValues *value, Args &args) { + wson_buffer *buffer = wson::runTimeValueToWson(value); + args.setWson(buffer); + } + + void + WeexConversionUtils::GetStringFromArgsDefaultUndefined(const std::vector &vars, int index, + std::string &result) { + + if (index >= vars.size()) { + result.assign("undefined"); + return; + } + convertJSRuntimeValueToStdString(vars[index], result); + } + + + void + WeexConversionUtils::GetStringFromArgsDefaultEmpty(const std::vector &vars, int index, + std::string &result) { + if (index >= vars.size()) { + result.assign(""); + return; + } + convertJSRuntimeValueToStdString(vars[index], result); + } + + bool WeexConversionUtils::GetCharOrJsonFromArgs(const std::vector &vars, int index, + std::string &result) { + if (index >= vars.size() || vars[index].get() == nullptr) { + return false; + } + LOG_CONVERSION("GetCharOrJsonFromArgs"); + if (vars[index]->IsMap() || vars[index]->IsArray()) { + WeexConversionUtils::RunTimeValuesOfObjectToJson(vars[index].get()).dump(result); + } else { + convertJSRuntimeValueToStdString(vars[index], result); + } + return true; + } + + void WeexConversionUtils::GetWsonFromArgs(const std::vector &vars, int index, + Args &args) { + if (index >= vars.size()) { + args.setWson((wson_buffer *) nullptr); + return; + } + ConvertRunTimeVaueToWson(vars[index].get(), args); + } + + void + WeexConversionUtils::ConvertRunTimeValueToWeexJSResult(unicorn::ScopeValues &value, WeexJSResult *jsResult) { + if (!value->IsArray() || nullptr == jsResult) { + LOGE("!value->IsArray() "); + return; + } + bool isAllNull = true; + const unicorn::Array *array = value->GetAsArray(); + if (nullptr == array) { + LOGE("nullptr == array"); + return; + } + for (size_t i = 0; i < array->Size(); i++) { + auto item = array->atIndex(i); + if (nullptr != item && !item->IsUndefined() && !item->IsNull()) { + isAllNull = false; + break; + } + } + if (isAllNull) { + LOGE("isAllNull "); + return; + } + char *buf = nullptr; + if (WeexEnv::getEnv()->useWson()) { + wson_buffer *buffer = wson::runTimeValueToWson(value.get()); + char *data = (char *) buffer->data; + jsResult->length = buffer->position; + buf = new char[jsResult->length + 1]; + memcpy(buf, data, jsResult->length); + wson_parser parser((char *) buffer->data); + LOGW("[exeJSWithResult] result wson :%s", parser.toStringUTF8().c_str()); + wson_buffer_free(buffer); + } else { + std::string json_str; + WeexConversionUtils::RunTimeValuesOfObjectToJson(value.get()).dump(json_str); + jsResult->length = json_str.length(); + buf = new char[jsResult->length + 1]; + memcpy(buf, json_str.c_str(), jsResult->length); + } + buf[jsResult->length] = '\0'; + jsResult->data.reset(buf); + } + + +// JSString* JSValue::toStringSlowCase(ExecState* exec, bool returnEmptyStringOnError) const +// { +// VM& vm = exec->vm(); +// auto scope = DECLARE_THROW_SCOPE(vm); +// +// auto errorValue = [&] () -> JSString* { +// if (returnEmptyStringOnError) +// return jsEmptyString(exec); +// return nullptr; +// }; +// +// ASSERT(!isString()); +// if (isInt32()) { +// auto integer = asInt32(); +// if (static_cast(integer) <= 9) +// return vm.smallStrings.singleCharacterString(integer + '0'); +// return jsNontrivialString(&vm, vm.numericStrings.add(integer)); +// } +// if (isDouble()) +// return jsString(&vm, vm.numericStrings.add(asDouble())); +// if (isTrue()) +// return vm.smallStrings.trueString(); +// if (isFalse()) +// return vm.smallStrings.falseString(); +// if (isNull()) +// return vm.smallStrings.nullString(); +// if (isUndefined()) +// return vm.smallStrings.undefinedString(); +// if (isSymbol()) { +// throwTypeError(exec, scope, ASCIILiteral("Cannot convert a symbol to a string")); +// return errorValue(); +// } +// +// ASSERT(isCell()); +// JSValue value = asCell()->toPrimitive(exec, PreferString); +// RETURN_IF_EXCEPTION(scope, errorValue()); +// ASSERT(!value.isObject()); +// JSString* result = value.toString(exec); +// RETURN_IF_EXCEPTION(scope, errorValue()); +// return result; +// } + + + /** + * impl wtf::string for histroy compatible (getCharOrJSONStringFromState in weexGlobalObject) + * const char* const nullString = "null"; + * const char* const trueString = "true"; + * const char* const falseString = "false"; + */ + void + WeexConversionUtils::convertJSRuntimeValueToStdString(const unicorn::ScopeValues ¶m, std::string &target) { + if (param->IsString()) { + std::string res; + param->GetAsString(&res); + target.assign(res); + } else if (param->IsUndefined()) { + target.assign("undefined"); + } else if (param->IsNull()) { + target.assign("null"); + } else if (param->IsInt()) { + int int_value = 0; + param->GetAsInteger(&int_value); + target.assign(std::to_string(int_value)); + } else if (param->IsDouble()) { + double double_value = 0; + param->GetAsDouble(&double_value); + target.assign(std::to_string(double_value)); + } else if (param->IsBool()) { + bool result = false; + param->GetAsBoolean(&result); + target.assign(result ? "true" : "false"); + } else { + LOGE("JSRuntimeValueToStdString ,not support type %d:", param->GetType()); + } + } + + void + WeexConversionUtils::GetJSONArgsFromArgsByWml(const std::vector &vars, int index, + std::string &args) { + if (index >= vars.size()) { + args.assign(""); + return; + } + if (vars[index]->IsString()) { + vars[index]->GetAsString(&args); + } else if (vars[index]->IsMap() || vars[index]->IsArray()) { + WeexConversionUtils::RunTimeValuesOfObjectToJson(vars[index].get()).dump(args); + } else { + args.assign(""); + return; + } + } + } +} \ No newline at end of file diff --git a/weex_core/Source/js_runtime/weex/utils/weex_conversion_utils.h b/weex_core/Source/js_runtime/weex/utils/weex_conversion_utils.h new file mode 100644 index 0000000000..b447650fae --- /dev/null +++ b/weex_core/Source/js_runtime/weex/utils/weex_conversion_utils.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 陈佩翰 on 2019/2/12. +// + +#ifndef PROJECT_JSON_BINDING_UTILS_H +#define PROJECT_JSON_BINDING_UTILS_H + +#include "include/WeexApiHeader.h" +#include "js_runtime/runtime/runtime_context.h" +//#include "js_runtime/dom/impl/weex_element.h" +#include "third_party/json11/json11.hpp" +#include "js_runtime/runtime/runtime_values.h" +#include "js_runtime/weex/object/args.h" + +namespace weex { + namespace jsengine { + class WeexConversionUtils { + public: + // static json11::Json convertElementToJSon(const Element *element); + + static bool convertKVToJSon(const std::string &name, const ::std::string &value, std::string &result); + + + static unicorn::ScopeValues + WeexValueToRuntimeValue(unicorn::EngineContext *context, VALUE_WITH_TYPE *weexValue); + + static void ConvertRunTimeValueToWeexJSResult(unicorn::ScopeValues &value, WeexJSResult *jsResult); + + + static void GetStringFromArgsDefaultEmpty(const std::vector &vars, int index, + std::string &result); + + static void GetStringFromArgsDefaultUndefined(const std::vector &vars, int index, + std::string &result); + + static bool + GetCharOrJsonFromArgs(const std::vector &vars, int index, std::string &result); + + static void + GetWsonFromArgs(const std::vector &vars, int index, Args &args); + + static void GetJSONArgsFromArgsByWml(const std::vector &vars, int index, + std::string &args); + + private: + + static void ConvertRunTimeVaueToWson(unicorn::RuntimeValues *value, Args &args); + + static json11::Json RunTimeValuesOfObjectToJson(unicorn::RuntimeValues *vars); + + static void convertJSRuntimeValueToStdString(const unicorn::ScopeValues ¶m, std::string &target); + + }; + + } +} + + +#endif //PROJECT_JSON_BINDING_UTILS_H diff --git a/weex_core/Source/js_runtime/weex/utils/weex_jsc_utils.cpp b/weex_core/Source/js_runtime/weex/utils/weex_jsc_utils.cpp new file mode 100644 index 0000000000..49a9b8e460 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/utils/weex_jsc_utils.cpp @@ -0,0 +1,155 @@ +/** + * 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 11/02/2018. +// + +#include "weex_jsc_utils.h" + +#include +#include + +#include "android/jsengine/object/weex_env.h" +#include "core/bridge/script_bridge.h" +#include "base/string_util.h" + + void printLogOnFileWithNameS(const char * name, const char *log) { + std::string string("/data/data/com.alibaba.weex/"); + string.append(name); + std::ofstream mcfile; + mcfile.open(string.c_str(), std::ios::app); + mcfile << log << std::endl; + mcfile.close(); +} + +std::string jString2String(const uint16_t *str, size_t length) { + return weex::base::to_utf8(const_cast(str), length); +} + + +std::string weexString2String(const WeexString *weexString) { + if (weexString != nullptr && weexString->length > 0) { + return jString2String(weexString->content, weexString->length); + } + + return ""; +} + +std::string char2String(const char* str) { + if(str == nullptr || strlen(str) == 0) + return ""; + + return str; + } + +WeexString *genWeexStringSS(const uint16_t *str, size_t length) { + size_t byteSize = length * sizeof(uint16_t); + auto *string = (WeexString *) malloc(byteSize + sizeof(WeexString)); + if (string == nullptr) + return nullptr; + + memset(string, 0, byteSize + sizeof(WeexString)); + string->length = length; + memcpy(string->content, str, byteSize); + return string; +} +WeexByteArray *genWeexByteArraySS(const char *str, size_t strLen) { + auto *ret = (WeexByteArray *) malloc(strLen + sizeof(WeexByteArray)); + + if (ret == nullptr) + return nullptr; + + memset(ret, 0, strLen + sizeof(WeexByteArray)); + + ret->length = strLen; + memcpy(ret->content, str, strLen); + + ret->content[strLen] = '\0'; + + return const_cast (ret); +} +void freeInitFrameworkParams(std::vector ¶ms) { + for (auto ¶m : params) { + free(param->type); + free(param->value); + free(param); + } +} + +void freeParams(std::vector ¶ms) { + for (auto ¶m : params) { + if (param->type == ParamsType::STRING || + param->type == ParamsType::JSONSTRING) { + free(param->value.string); + } + if (param->type == ParamsType::BYTEARRAY) { + free(param->value.byteArray); + } + free(param); + } +} +void doUpdateGlobalSwitchConfig(const char *config) { + if (!config) { + return; + } + LOGE("doUpdateGlobalSwitchConfig %s", config); + if (strstr(config, "wson_off") != NULL) { + WeexEnv::getEnv()->setUseWson(false); + } else { + WeexEnv::getEnv()->setUseWson(true); + } +} + + +uint64_t microTime() { + struct timeval tv; + + gettimeofday(&tv, nullptr); + + return (((uint64_t) tv.tv_sec) * MICROSEC + tv.tv_usec); +} + + +int __atomic_inc(volatile int *ptr) { + return __sync_fetch_and_add(ptr,1); +} +static int taskIdGenerator = 0; +int genTaskId(){ + return __atomic_inc(&taskIdGenerator); +} + + +WeexByteArray *IPCByteArrayToWeexByteArray(const IPCByteArray *byteArray) { + return genWeexByteArraySS(byteArray->content, byteArray->length); +} + + +namespace WEEXICU { + unique_fd::unique_fd(int fd) + : m_fd(fd) { + } + + unique_fd::~unique_fd() { + close(m_fd); + } + + int unique_fd::get() const { + return m_fd; + } +} diff --git a/weex_core/Source/js_runtime/weex/utils/weex_jsc_utils.h b/weex_core/Source/js_runtime/weex/utils/weex_jsc_utils.h new file mode 100644 index 0000000000..0d4d7b45fb --- /dev/null +++ b/weex_core/Source/js_runtime/weex/utils/weex_jsc_utils.h @@ -0,0 +1,251 @@ +/** + * 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 11/02/2018. +// + +#ifndef WEEXV8_UTILS_H +#define WEEXV8_UTILS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "include/WeexApiValue.h" + +#include "base/base64/base64.h" +#include "base/crash/crash_handler.h" +#include "base/utils/log_utils.h" +#include "include/WeexApiHeader.h" + +#include "js_runtime/weex/object/args.h" + +#include "third_party/IPC/Buffering/IPCBuffer.h" +#include "third_party/IPC/IPCArguments.h" +#include "third_party/IPC/IPCByteArray.h" +#include "third_party/IPC/IPCHandler.h" +#include "third_party/IPC/IPCListener.h" +#include "third_party/IPC/IPCMessageJS.h" +#include "third_party/IPC/IPCResult.h" +#include "third_party/IPC/IPCSender.h" +#include "third_party/IPC/IPCString.h" +#include "third_party/IPC/IPCType.h" +#include "third_party/IPC/IPCFutexPageQueue.h" +#include "third_party/IPC/IPCException.h" +#include "third_party/IPC/Serializing/IPCSerializer.h" +//#include "include/JavaScriptCore/runtime/StructureInlines.h" +//#include "include/JavaScriptCore/runtime/JSCJSValueInlines.h" + +#if !defined(PATH_MAX) +#define PATH_MAX 4096 +#endif + +#define MICROSEC ((uint64_t) 1e6) + +#define TIMESPCE 1000 + +using namespace WeexCore; + +extern bool config_use_wson; + +std::string jString2String(const uint16_t *str, size_t length); + + +std::string weexString2String(const WeexString *weexString); + +std::string char2String(const char* str); + +//void addString(IPCSerializer *serializer, const String &s); + +WeexString *genWeexStringSS(const uint16_t *str, size_t length); +WeexByteArray *genWeexByteArraySS(const char *str, size_t strLen); + +void freeInitFrameworkParams(std::vector ¶ms); +void freeParams(std::vector ¶ms); +void printLogOnFileWithNameS(const char * name,const char *log); + + +void doUpdateGlobalSwitchConfig(const char *config); + +//String exceptionToString(JSGlobalObject *globalObject, JSValue exception); + +uint64_t microTime(); +int __atomic_inc(volatile int *ptr); +int genTaskId() ; +WeexByteArray *IPCByteArrayToWeexByteArray(const IPCByteArray *byteArray); + + +namespace WEEXICU { + + class unique_fd { + public: + explicit unique_fd(int fd); + + ~unique_fd(); + + int get() const; + + private: + int m_fd; + }; + + static std::string __attribute__((noinline)) findPath(); + + static void findPath(std::string &executablePath, std::string &icuDataPath) { + unsigned long target = reinterpret_cast(__builtin_return_address(0)); + FILE *f = fopen("/proc/self/maps", "r"); + if (!f) { + return; + } + char buffer[256]; + char *line; + while ((line = fgets(buffer, 256, f))) { + if (icuDataPath.empty() && strstr(line, "icudt")) { + icuDataPath.assign(strstr(line, "/")); + icuDataPath = icuDataPath.substr(0, icuDataPath.length() - 1); + continue; + } + char *end; + unsigned long val; + errno = 0; + val = strtoul(line, &end, 16); + if (errno) + continue; + if (val > target) + continue; + end += 1; + errno = 0; + val = strtoul(end, &end, 16); + if (errno) + continue; + if (val > target) { + char *s = strstr(end, "/"); + if (s != nullptr) + executablePath.assign(s); + std::size_t found = executablePath.rfind('/'); + if (found != std::string::npos) { + executablePath = executablePath.substr(0, found); + } + } + if (!executablePath.empty() + && !icuDataPath.empty()) { + break; + } + } + fclose(f); + return; + } + + +#define FAIL_WITH_STRERROR(tag) \ + LOGE(" fails: %s.\n", strerror(errno)); \ + return false; + +#define MAYBE_FAIL_WITH_ICU_ERROR(s) \ + if (status != U_ZERO_ERROR) {\ + LOGE("Couldn't initialize ICU (" "): %s (%s)" "\n", u_errorName(status), path.c_str()); \ + return false; \ + } + extern "C" { +// void udata_setCommonData(const void *data, UErrorCode *pErrorCode); + } + +// static bool mapIcuData(const std::string &path) { +// // Open the file and get its length. +// unique_fd fd(open(path.c_str(), O_RDONLY)); +// if (fd.get() == -1) { +// FAIL_WITH_STRERROR("open"); +// } +// struct stat sb; +// if (fstat(fd.get(), &sb) == -1) { +// FAIL_WITH_STRERROR("stat"); +// } +// +// // Map it. +// void *data = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd.get(), 0); +// if (data == MAP_FAILED) { +// FAIL_WITH_STRERROR("mmap"); +// } +// +// // Tell the kernel that accesses are likely to be random rather than sequential. +// if (madvise(data, sb.st_size, MADV_RANDOM) == -1) { +// FAIL_WITH_STRERROR("madvise(MADV_RANDOM)"); +// } +// +// UErrorCode status = U_ZERO_ERROR; +// +// // Tell ICU to use our memory-mapped data. +// udata_setCommonData(data, &status); +// MAYBE_FAIL_WITH_ICU_ERROR("udata_setCommonData"); +// +// return true; +// } + + static bool initICUEnv(bool multiProcess) { + static bool isInit = false; + if (isInit) + return true; + + char *path; + if (!multiProcess) { + std::string executablePath; + std::string icuDataPath; + findPath(executablePath, icuDataPath); + path = new char[icuDataPath.length() + 1]; + std::strcpy(path, icuDataPath.c_str()); + } else { + path = getenv("ICU_DATA_PATH"); + } + LOGE("initICUEnv patch:%s", path); + + if (!path) { + return false; + } + if (!dlopen("libicuuc.so", RTLD_NOW)) { + LOGE("load icuuc so"); + return false; + } + if (!dlopen("libicui18n.so", RTLD_NOW)) { + LOGE("load icui18n so"); + return false; + } +// if (!initICU()) { +// LOGE("initICU failed"); +// return false; +// } + if (strlen(path) > 0) { + isInit = true; + return true;//mapIcuData(std::string(path)); + } + return false; + } + +} + +#endif //WEEXV8_UTILS_H diff --git a/weex_core/Source/js_runtime/weex/utils/wson_for_runtime.cpp b/weex_core/Source/js_runtime/weex/utils/wson_for_runtime.cpp new file mode 100644 index 0000000000..f81185debb --- /dev/null +++ b/weex_core/Source/js_runtime/weex/utils/wson_for_runtime.cpp @@ -0,0 +1,230 @@ +/** + * 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 陈佩翰 on 2019/2/25. +// + +#include +#include "wson/wson.h" +#include "wson/wson_parser.h" +#include "wson_for_runtime.h" +#include "base/string_util.h" + +#include "js_runtime/utils/log_utils.h" + + + +inline static std::string wson16ToString(uint16_t *src, int length) { + std::string str; + auto * decodeBuffer = new char[length * 2]; + wson::utf16_convert_to_utf8_string(src, length/sizeof(uint16_t), decodeBuffer, str); + delete []decodeBuffer; + return str; +} + +namespace wson { + + unicorn::RuntimeValues * + convertWsonToRuntimeValue(unicorn::EngineContext *context, wson_buffer *buffer) { + uint8_t type = wson_next_type(buffer); + switch (type) { + case WSON_UINT8_STRING_TYPE: { + LOG_CONVERSION("[toRunTimeValueFromWson][string][start]"); + int size = wson_next_uint(buffer); + uint8_t *utf8 = wson_next_bts(buffer, size); + std::string string_utf_8 = std::string(reinterpret_cast(utf8), size); + LOG_CONVERSION("[toRunTimeValueFro mWson][string][end] :%s", string_utf_8.c_str()); + return new unicorn::RuntimeValues(string_utf_8); + } + case WSON_STRING_TYPE: + case WSON_NUMBER_BIG_INT_TYPE: + case WSON_NUMBER_BIG_DECIMAL_TYPE: { + LOG_CONVERSION("[toRunTimeValueFromWson][string_utf_16][start]"); + int length = wson_next_uint(buffer); + uint16_t * utf16 = ( uint16_t *)wson_next_bts(buffer, length); + std::string string_utf_8 = wson16ToString(utf16,length); +// LOGE("dyydyy [toRunTimeValueFromWson][string_utf_16][end] :%s", string_utf_8.c_str()); + return new unicorn::RuntimeValues(string_utf_8); + } + break; + case WSON_ARRAY_TYPE: { + LOG_CONVERSION("[toRunTimeValueFromWson][array][start]"); + uint32_t length = wson_next_uint(buffer); + auto runtime_array = unicorn::Array::CreateFromNative(context, unicorn::RuntimeValues::MakeNull()); + for (uint32_t i = 0; i < length; i++) { + if (wson_has_next(buffer)) { + runtime_array->PushBack(convertWsonToRuntimeValue(context, buffer)); + } else { + break; + } + } + LOG_CONVERSION("[toRunTimeValueFromWson][array][end]"); + return new unicorn::RuntimeValues(std::move(runtime_array)); + } + break; + case WSON_MAP_TYPE: { + LOG_CONVERSION("[toRunTimeValueFromWson][map][start]"); + uint32_t length = wson_next_uint(buffer); + std::unique_ptr runtime_map = unicorn::Map::CreateFromNative(context, + unicorn::RuntimeValues::MakeNull()); + for (uint32_t i = 0; i < length; i++) { + if (wson_has_next(buffer)) { + int length = wson_next_uint(buffer); + uint16_t * utf16 = ( uint16_t *)wson_next_bts(buffer, length); + std::string name_utf_8 = wson16ToString(utf16,length); + LOG_CONVERSION("[toRunTimeValueFromWson][map][itemkey] :%s", name_utf_8.c_str()); + runtime_map->Insert(name_utf_8, convertWsonToRuntimeValue(context, buffer)); + + } else { + break; + } + } + LOG_CONVERSION("[toRunTimeValueFromWson][map][end]"); + return new unicorn::RuntimeValues(std::move(runtime_map)); + } + break; + case WSON_NUMBER_INT_TYPE: { + int32_t num = wson_next_int(buffer); + return new unicorn::RuntimeValues(num); + } + break; + case WSON_BOOLEAN_TYPE_TRUE: { + return new unicorn::RuntimeValues(true); + } + break; + case WSON_BOOLEAN_TYPE_FALSE: { + return new unicorn::RuntimeValues(false); + } + break; + case WSON_NUMBER_DOUBLE_TYPE: { + double num = wson_next_double(buffer); + return new unicorn::RuntimeValues(num); + } + break; + case WSON_NUMBER_FLOAT_TYPE: { + float num = wson_next_float(buffer); + return new unicorn::RuntimeValues(num); + } + break; + case WSON_NUMBER_LONG_TYPE: { + int64_t num = wson_next_long(buffer); + return new unicorn::RuntimeValues((double) num); + } + break; + case WSON_NULL_TYPE: { + return new unicorn::RuntimeValues(nullptr); + } + default: { + LOGE("[WsonToRuntimeValue] unsupport data type in default case!!"); + return new unicorn::RuntimeValues(nullptr); + } + } + } + + unicorn::ScopeValues toRunTimeValueFromWson(unicorn::EngineContext *context, void *data, int length) { + wson_buffer *buffer = wson_buffer_from(data, length); + auto ret = convertWsonToRuntimeValue(context, buffer); + +#ifdef LOG_CONVERSION_SWITCH + wson_parser parser((char *) buffer->data); + LOG_CONVERSION("[WeexValueToRuntimeValue][wson] :%s", parser.toStringUTF8().c_str()); +#endif + + + + buffer->data = nullptr; + wson_buffer_free(buffer); + return unicorn::ScopeValues(ret); + } + + void pushStringToWsonBuffer(wson_buffer *buffer, std::string str_utf_8) { + std::u16string s = weex::base::to_utf16(const_cast(str_utf_8.c_str()), str_utf_8.length()); + size_t length = s.length(); + wson_push_type(buffer, WSON_STRING_TYPE); + wson_push_uint(buffer, length * sizeof(uint16_t)); + wson_push_bytes(buffer, s.c_str(), s.length() * sizeof(uint16_t)); + } + + void pushMapKeyToBuffer(wson_buffer *buffer, std::string str_utf_8) { + std::u16string s = weex::base::to_utf16(const_cast(str_utf_8.c_str()), str_utf_8.length()); + size_t length = s.length(); + wson_push_uint(buffer, length * sizeof(uint16_t)); + wson_push_bytes(buffer, s.c_str(), s.length() * sizeof(uint16_t)); + } + + + void putValuesToWson(unicorn::RuntimeValues *value, wson_buffer *buffer) { + if (value->IsUndefined() || value->IsNull()) { + wson_push_type_null(buffer); + } else if (value->IsInt()) { + int num = -1; + value->GetAsInteger(&num); + wson_push_type_int(buffer, num); + } else if (value->IsDouble()) { + double num = -1; + value->GetAsDouble(&num); + wson_push_type_double(buffer, num); + } else if (value->IsBool()) { + bool flag = false; + value->GetAsBoolean(&flag); + wson_push_type_boolean(buffer, flag ? 1 : 0); + } else if (value->IsString()) { + std::string str_utf_8; + value->GetAsString(&str_utf_8); + pushStringToWsonBuffer(buffer, str_utf_8); + } else if (value->IsArray()) { + auto array = value->GetAsArray(); + uint32_t length = array->Size(); + wson_push_type_array(buffer, length); + for (uint32_t i = 0; i < length; i++) { + auto item = array->atIndex(i); + putValuesToWson(item, buffer); + } + } else if (value->IsMap()) { + auto map = value->GetAsMap()->GetMap(); + uint32_t map_size = map.size(); + uint32_t undefinedOrFunctionSize = 0; + for (auto item:map) { + if (item.second->IsUndefined() || item.second->IsNull() || item.second->IsFunction() || + item.second->IsObject()) { + undefinedOrFunctionSize++; + LOG_CONVERSION("[wson]putValuesToWson data type not match ,type :%d ", item.second->GetType()); + } + } + wson_push_type_map(buffer, map_size - undefinedOrFunctionSize); + for (auto item:map) { + if (item.second->IsUndefined() || item.second->IsNull() || item.second->IsFunction() || + item.second->IsObject()) { + continue; + } + pushMapKeyToBuffer(buffer, item.first); + putValuesToWson(item.second, buffer); + } + } else { + LOGE("[wson][else] putValuesToWson data type not match ,type :%d ", value->GetType()); + } + } + + + wson_buffer *runTimeValueToWson(unicorn::RuntimeValues *value) { + wson_buffer *buffer = wson_buffer_new(); + putValuesToWson(value, buffer); + return buffer; + } +} \ No newline at end of file diff --git a/weex_core/Source/js_runtime/weex/utils/wson_for_runtime.h b/weex_core/Source/js_runtime/weex/utils/wson_for_runtime.h new file mode 100644 index 0000000000..6111601891 --- /dev/null +++ b/weex_core/Source/js_runtime/weex/utils/wson_for_runtime.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. + */ +// +// Created by 陈佩翰 on 2019/2/25. +// + +#ifndef PROJECT_WSON_FOR_RUNTIME_H +#define PROJECT_WSON_FOR_RUNTIME_H + + +#include "js_runtime/runtime/runtime_values.h" +#include "js_runtime/runtime/runtime_context.h" + +namespace wson { + unicorn::ScopeValues toRunTimeValueFromWson(unicorn::EngineContext *context, void *data, int length); + + wson_buffer *runTimeValueToWson(unicorn::RuntimeValues *value); + +} + + +#endif //PROJECT_WSON_FOR_RUNTIME_H diff --git a/weex_core/debug.sh b/weex_core/debug.sh index cb10c74ed8..208247d1fe 100755 --- a/weex_core/debug.sh +++ b/weex_core/debug.sh @@ -1,5 +1,5 @@ cd ../android/sdk -gradle compileDebugSources +../gradlew assembleDebug cd .. cp sdk/build/intermediates/cmake/debug/obj/armeabi/libweexcore.so sdk/libs/armeabi/libweexcore.so cp sdk/build/intermediates/cmake/debug/obj/armeabi-v7a/libweexcore.so sdk/libs/armeabi-v7a/libweexcore.so diff --git a/weex_core/release.sh b/weex_core/release.sh index 3337c54d49..7bff147eec 100755 --- a/weex_core/release.sh +++ b/weex_core/release.sh @@ -1,19 +1,28 @@ cd ../android -rm -rf sdk/build/intermediates/bundles/default/jni/* -./gradlew clean assembleRelease -cp sdk/build/intermediates/bundles/default/jni/armeabi/libweexcore.so sdk/libs/armeabi/libweexcore.so -cp sdk/build/intermediates/bundles/default/jni/armeabi-v7a/libweexcore.so sdk/libs/armeabi-v7a/libweexcore.so -cp sdk/build/intermediates/bundles/default/jni/x86/libweexcore.so sdk/libs/x86/libweexcore.so +#rm -rf sdk/build/intermediates/bundles/default/jni/* +./gradlew assembleRelease clean -PbuildRuntimeApi=true + +#cp sdk/build/intermediates/bundles/default/jni/armeabi/libweexcore.so sdk/libs/armeabi/libweexcore.so +#cp sdk/build/intermediates/bundles/default/jni/armeabi-v7a/libweexcore.so sdk/libs/armeabi-v7a/libweexcore.so +#cp sdk/build/intermediates/bundles/default/jni/x86/libweexcore.so sdk/libs/x86/libweexcore.so # cp jss so -cp sdk/build/intermediates/bundles/default/jni/armeabi/libweexjss.so sdk/libs/armeabi/libweexjss.so -cp sdk/build/intermediates/bundles/default/jni/armeabi-v7a/libweexjss.so sdk/libs/armeabi-v7a/libweexjss.so -cp sdk/build/intermediates/bundles/default/jni/x86/libweexjss.so sdk/libs/x86/libweexjss.so +cp sdk/build/intermediates/intermediate-jars/release/jni/arm64-v8a/libweexjss.so sdk/libs/arm64-v8a/libweexjssr.so +cp sdk/build/intermediates/intermediate-jars/release/jni/armeabi-v7a/libweexjss.so sdk/libs/armeabi-v7a/libweexjssr.so +cp sdk/build/intermediates/intermediate-jars/release/jni/x86/libweexjss.so sdk/libs/x86/libweexjssr.so + + + # back up obj -#rm -rf ~/Desktop/weex_so_armeabi -#mkdir ~/Desktop/weex_so_armeabi -#cp sdk/build/intermediates/cmake/release/obj/armeabi/libweexjss.so ~/Desktop/weex_so_armeabi/ -#cp sdk/build/intermediates/cmake/release/obj/armeabi/libweexcore.so ~/Desktop/weex_so_armeabi/ \ No newline at end of file +rm -rf ~/Desktop/weex_so_armeabi +mkdir ~/Desktop/weex_so_armeabi +cp sdk/build/intermediates/cmake/release/obj/arm64-v8a/libweexjss.so ~/Desktop/weex_so_armeabi/libweexjssr_64_v8a.so +cp sdk/build/intermediates/cmake/release/obj/armeabi-v7a/libweexjss.so ~/Desktop/weex_so_armeabi/libweexjssr_v7a.so +cp sdk/build/intermediates/cmake/release/obj/x86/libweexjss.so ~/Desktop/weex_so_armeabi/libweexjssr_x86.so + + + +./gradlew assembleRelease -PbuildRuntimeApi=false \ No newline at end of file