diff --git a/frameworks/src/core/context/js_app_context.cpp b/frameworks/src/core/context/js_app_context.cpp index 61635c5c180e20ed102d9700d64f1b7a3621fc15..3f3b603de9330d9ecdd521d9ea0f4012e5e9e59c 100755 --- a/frameworks/src/core/context/js_app_context.cpp +++ b/frameworks/src/core/context/js_app_context.cpp @@ -50,9 +50,9 @@ void JsAppContext::ClearContext() /** * return value should be released by caller when it's not used */ -jerry_value_t JsAppContext::Eval(const char * const jsFileFullPath, size_t fileNameLength, bool isAppEval) const +jerry_value_t JsAppContext::Eval(char *fullPath, size_t fullPathLength, bool isAppEval) const { - if ((jsFileFullPath == nullptr) || (fileNameLength == 0)) { + if ((fullPath == nullptr) || (fullPathLength == 0)) { HILOG_ERROR(HILOG_MODULE_ACE, "Failed to eval js code cause by empty JavaScript script."); ACE_ERROR_CODE_PRINT(EXCE_ACE_ROUTER_REPLACE_FAILED, EXCE_ACE_PAGE_INDEX_MISSING); return UNDEFINED; @@ -60,23 +60,24 @@ jerry_value_t JsAppContext::Eval(const char * const jsFileFullPath, size_t fileN uint32_t contentLength = 0; START_TRACING(PAGE_CODE_LOAD); - bool snapshotMode = JsAppEnvironment::GetInstance()->IsSnapshotMode(); - char *jsCode = ReadFile(jsFileFullPath, contentLength, snapshotMode); + bool isSnapshotMode = JsAppEnvironment::GetInstance()->IsSnapshotMode(); + char *jsCode = EvaluateFile(isSnapshotMode, contentLength, fullPath, fullPathLength); STOP_TRACING(); if ((jsCode == nullptr) || (contentLength > FILE_CONTENT_LENGTH_MAX)) { HILOG_ERROR(HILOG_MODULE_ACE, "empty js file or length is incorrect, eval user code failed"); ACE_ERROR_CODE_PRINT(EXCE_ACE_ROUTER_REPLACE_FAILED, EXCE_ACE_PAGE_FILE_READ_FAILED); + ACE_FREE(jsCode); return UNDEFINED; } START_TRACING(PAGE_CODE_EVAL); jerry_value_t viewModel = UNDEFINED; - if (snapshotMode) { + if (isSnapshotMode) { const uint32_t *snapshotContent = reinterpret_cast(jsCode); viewModel = jerry_exec_snapshot(snapshotContent, contentLength, 0, 1); } else { const jerry_char_t *jsScript = reinterpret_cast(jsCode); - jerry_value_t retValue = jerry_parse(reinterpret_cast(jsFileFullPath), fileNameLength, + jerry_value_t retValue = jerry_parse(reinterpret_cast(fullPath), fullPathLength, jsScript, contentLength, JERRY_PARSE_NO_OPTS); if (jerry_value_is_error(retValue)) { ACE_ERROR_CODE_PRINT(EXCE_ACE_ROUTER_REPLACE_FAILED, EXCE_ACE_PAGE_JS_EVAL_FAILED); @@ -108,6 +109,40 @@ jerry_value_t JsAppContext::Eval(const char * const jsFileFullPath, size_t fileN return viewModel; } +char *JsAppContext::EvaluateFile(bool &isSnapshotMode, + uint32_t &outLength, + char *fullPath, + size_t fullPathLength) const +{ + if (fullPath == nullptr || fullPathLength == 0) { + return nullptr; + } + const uint8_t fileSuffixLength = 3; // file suffix is fixed, .js or .bc + size_t filePathLen = strlen(fullPath); + if ((filePathLen == 0) || (filePathLen != fullPathLength) || (fullPathLength < fileSuffixLength)) { + return nullptr; + } + outLength = 0; + char *jsCode = ReadFile(fullPath, outLength, isSnapshotMode); + if ((jsCode != nullptr) && (outLength <= FILE_CONTENT_LENGTH_MAX)) { + // read successfully + return jsCode; + } + // make sure the memory is freeed + ACE_FREE(jsCode); + + const char * const anotherSuffx = isSnapshotMode ? ".js" : ".bc"; + // change file suffix to another mode file + if (strcpy_s((fullPath + (fullPathLength - fileSuffixLength)), (fileSuffixLength + 1), anotherSuffx) != EOK) { + return nullptr; + } + // snapshot mode changed to another + isSnapshotMode = !isSnapshotMode; + HILOG_ERROR(HILOG_MODULE_ACE, "JS mode changed unexpected [%d]", isSnapshotMode); + jsCode = ReadFile(fullPath, outLength, isSnapshotMode); + return jsCode; +} + void JsAppContext::SetGlobalNamedProperty(bool isAppEval, jerry_value_t viewModel) const { jerry_value_t globalObject = jerry_get_global_object(); diff --git a/frameworks/src/core/context/js_app_context.h b/frameworks/src/core/context/js_app_context.h index 21a49d559cd5213fd362b0614e6b271b92c7f43b..c0315daede83687588cd4a26d4593c1c542abc22 100755 --- a/frameworks/src/core/context/js_app_context.h +++ b/frameworks/src/core/context/js_app_context.h @@ -40,11 +40,11 @@ public: /** * @brief eval user's JS Code and return FeatureAbility object * - * @param: jsFileFullPath js file full path - * @param: fileNameLength the given file name length + * @param: fullPath js file full path + * @param: fullPathLength the given file name length * @param: the flag for app eval or page eval.True is eval flag. */ - jerry_value_t Eval(const char * const jsFileFullPath, size_t fileNameLength, bool isAppEval) const; + jerry_value_t Eval(char *fullPath, size_t fullPathLength, bool isAppEval) const; /** * @brief call FeatureAbility's render function * @@ -148,6 +148,17 @@ private: void ReleaseAbilityInfo(); void SetGlobalNamedProperty(bool isAppEval, jerry_value_t viewModel) const; + /** + * @brief try read the target mode file content, if failed, change to read another mode + * + * @param: isSnapshotMode target mode, can be adjusted to the proper mode + * @param: outLength the reading content length + * @param: fullPath js file full path + * @param: fullPathLength the given file name length + * + * @return the target mode file content or nullptr for reading failure + */ + char *EvaluateFile(bool &isSnapshotMode, uint32_t &outLength, char *fullPathPath, size_t fullPathLength) const; char *currentBundleName_ = nullptr; char *currentAbilityPath_ = nullptr; char *currentJsPath_ = nullptr; diff --git a/frameworks/src/core/router/js_page_state_machine.cpp b/frameworks/src/core/router/js_page_state_machine.cpp index 0ef71287d1391a6fe258cfcb0a78a2a400fb1d37..33db0a41b346fcd8a5e1ccd3ce6c185a55888652 100755 --- a/frameworks/src/core/router/js_page_state_machine.cpp +++ b/frameworks/src/core/router/js_page_state_machine.cpp @@ -213,10 +213,8 @@ bool StateMachine::BindUri(jerry_value_t &jsRes) return false; } // check5:object's uri is not existed, need to move - char *fullPath = RelocateJSSourceFilePath(appRootPath_, jsPagePath_); appContext_->SetCurrentJsPath(jsPagePath_); - if (GetFileSize(fullPath) == 0) { - ACE_FREE(fullPath); + if (!CheckJSSourceFile()) { ace_free(uri_); uri_ = nullptr; HILOG_ERROR(HILOG_MODULE_ACE, "statemachine init failed as js file isn't existed."); @@ -224,10 +222,44 @@ bool StateMachine::BindUri(jerry_value_t &jsRes) reinterpret_cast("route target doesn't existed.")); return false; } - ACE_FREE(fullPath); return true; } +bool StateMachine::CheckJSSourceFile() const +{ + char *fullPath = RelocateJSSourceFilePath(appRootPath_, jsPagePath_); + if (fullPath == nullptr) { + return false; + } + + bool result = false; + do { + size_t pathLength = strlen(fullPath); + const uint8_t fileSuffixLength = 3; + if ((pathLength == 0) || (pathLength > PATH_LENGTH_MAX) || (pathLength < fileSuffixLength)) { + break; + } + + result = (GetFileSize(fullPath) > 0); + if (result) { + // try first one mode successfully + break; + } + + const char * const anotherSuffix = (JsAppEnvironment::GetInstance()->IsSnapshotMode()) ? ".js" : ".bc"; + // change file suffix to another mode file + if (strcpy_s((fullPath + (pathLength - fileSuffixLength)), (fileSuffixLength + 1), anotherSuffix) != EOK) { + break; + } + result = (GetFileSize(fullPath) > 0); + } while (0); + + ace_free(fullPath); + fullPath = nullptr; + + return result; +} + void StateMachine::BindParameters() { jerry_value_t params = jerryx_get_property_str(object_, ROUTER_PAGE_PARAMS); diff --git a/frameworks/src/core/router/js_page_state_machine.h b/frameworks/src/core/router/js_page_state_machine.h index dd4bd793929aa8fb15ec8858e8a078abde8b548e..9304a559c6d6aafc6f60f602ac4b5b6b4570c86b 100644 --- a/frameworks/src/core/router/js_page_state_machine.h +++ b/frameworks/src/core/router/js_page_state_machine.h @@ -82,6 +82,7 @@ private: int GenerateJsPagePath(const char * const uri); void DeleteViewModelProperties() const; void ReleaseRootObject() const; + bool CheckJSSourceFile() const; private: int8_t currentState_;