1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #include "script_interpreter.h" 16 #include <algorithm> 17 #include <fstream> 18 #include "dump.h" 19 #include "script_context.h" 20 #include "script_manager_impl.h" 21 #include "scanner.h" 22 #include "script_utils.h" 23 24 using namespace std; 25 26 namespace Uscript { 27 static int32_t g_instanceId = 0; 28 ExecuteScript(ScriptManagerImpl * manager,Hpackage::PkgManager::StreamPtr pkgStream)29 int32_t ScriptInterpreter::ExecuteScript(ScriptManagerImpl *manager, Hpackage::PkgManager::StreamPtr pkgStream) 30 { 31 if (pkgStream == nullptr) { 32 USCRIPT_LOGE("Param error"); 33 UPDATER_LAST_WORD(USCRIPT_INVALID_PARAM); 34 return USCRIPT_INVALID_PARAM; 35 } 36 USCRIPT_LOGI("ExecuteScript %s", pkgStream->GetFileName().c_str()); 37 auto inter = new (std::nothrow) ScriptInterpreter(manager); 38 if (inter == nullptr) { 39 USCRIPT_LOGE("Fail to create ScriptInterpreter for script %s", pkgStream->GetFileName().c_str()); 40 UPDATER_LAST_WORD(USCRIPT_ERROR_CREATE_OBJ); 41 return USCRIPT_ERROR_CREATE_OBJ; 42 } 43 int32_t ret = inter->LoadScript(pkgStream); 44 if (ret != USCRIPT_SUCCESS) { 45 USCRIPT_LOGE("Fail to loadScript script %s", pkgStream->GetFileName().c_str()); 46 UPDATER_LAST_WORD(USCRIPT_ERROR_CREATE_OBJ); 47 return ret; 48 } 49 ret = inter->Execute(); 50 delete inter; 51 inter = nullptr; 52 USCRIPT_LOGI("ExecuteScript finish ret: %d script: %s ", 53 ret, pkgStream->GetFileName().c_str()); 54 return ret; 55 } 56 ScriptInterpreter(ScriptManagerImpl * manager)57 ScriptInterpreter::ScriptInterpreter(ScriptManagerImpl *manager) : scriptManager_(manager) 58 { 59 instanceId_ = g_instanceId++; 60 } 61 ~ScriptInterpreter()62 ScriptInterpreter::~ScriptInterpreter() 63 { 64 delete statements_; 65 auto iter = functions_.begin(); 66 while (iter != functions_.end()) { 67 auto entry = iter->second; 68 if (entry) { 69 delete entry; 70 } 71 iter = functions_.erase(iter); 72 } 73 functions_.clear(); 74 contextStack_.clear(); 75 } 76 LoadScript(Hpackage::PkgManager::StreamPtr pkgStream)77 int32_t ScriptInterpreter::LoadScript(Hpackage::PkgManager::StreamPtr pkgStream) 78 { 79 scanner_ = std::make_unique<Scanner>(this); 80 parser_ = std::make_unique<Parser>(scanner_.get(), this); 81 scanner_->set_debug(0); 82 scanner_->SetPkgStream(pkgStream); 83 int32_t ret = parser_->parse(); 84 return ret; 85 } 86 Execute()87 int32_t ScriptInterpreter::Execute() 88 { 89 UScriptContextPtr context = std::make_shared<UScriptInterpretContext>(true); 90 UScriptStatementResult result = statements_->Execute(*this, context); 91 INTERPRETER_LOGD(*this, context, "statements_ execute result %s ", 92 UScriptStatementResult::ScriptToString(&result).c_str()); 93 if (result.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR) { 94 return result.GetError(); 95 } 96 return USCRIPT_SUCCESS; 97 } 98 AddFunction(ScriptFunction * function)99 int32_t ScriptInterpreter::AddFunction(ScriptFunction *function) 100 { 101 if (functions_.find(function->GetFunctionName()) != functions_.end()) { 102 USCRIPT_LOGI("Fail to add function %s, function exist", function->GetFunctionName().c_str()); 103 return USCRIPT_SUCCESS; 104 } 105 functions_[function->GetFunctionName()] = function; 106 return USCRIPT_SUCCESS; 107 } 108 FindFunction(const std::string & name)109 ScriptFunction* ScriptInterpreter::FindFunction(const std::string &name) 110 { 111 if (functions_.find(name) != functions_.end()) { 112 return functions_[name]; 113 } 114 return nullptr; 115 } 116 ExecuteFunction(UScriptContextPtr context,const std::string & name,ScriptParams * params)117 UScriptValuePtr ScriptInterpreter::ExecuteFunction(UScriptContextPtr context, const std::string &name, 118 ScriptParams *params) 119 { 120 ScriptFunction *function = FindFunction(name); 121 if (function == nullptr) { 122 USCRIPT_LOGI("Fail to find function %s", name.c_str()); 123 return std::make_shared<ErrorValue>(USCRIPT_NOTEXIST_INSTRUCTION); 124 } else { 125 return function->Execute(*this, context, params); 126 } 127 } 128 FindVariable(UScriptContextPtr local,std::string id)129 UScriptValuePtr ScriptInterpreter::FindVariable(UScriptContextPtr local, std::string id) 130 { 131 for (auto context = contextStack_.rbegin(); context != contextStack_.rend(); context++) { 132 UScriptValuePtr variable = (*context)->FindVariable(*this, id); 133 if (variable != nullptr) { 134 return variable; 135 } 136 if ((*context)->IsTop()) { 137 break; 138 } 139 } 140 return nullptr; 141 } 142 UpdateVariable(UScriptContextPtr local,std::string id,UScriptValuePtr var)143 UScriptValuePtr ScriptInterpreter::UpdateVariable(UScriptContextPtr local, std::string id, UScriptValuePtr var) 144 { 145 for (auto context = contextStack_.rbegin(); context != contextStack_.rend(); context++) { 146 UScriptValuePtr variable = (*context)->FindVariable(*this, id); 147 if (variable != nullptr) { 148 (*context)->UpdateVariable(*this, id, var); 149 } 150 if ((*context)->IsTop()) { 151 break; 152 } 153 } 154 return nullptr; 155 } 156 AddStatement(UScriptStatement * statement)157 void ScriptInterpreter::AddStatement(UScriptStatement *statement) 158 { 159 if (statements_ == nullptr) { 160 statements_ = UScriptStatementList::CreateInstance(statement); 161 } else { 162 statements_->AddScriptStatement(statement); 163 } 164 } 165 IsNativeFunction(std::string name)166 bool ScriptInterpreter::IsNativeFunction(std::string name) 167 { 168 return scriptManager_->FindInstruction(name) != nullptr; 169 } 170 ExecuteNativeFunc(UScriptContextPtr context,const std::string & name,ScriptParams * params)171 UScriptValuePtr ScriptInterpreter::ExecuteNativeFunc(UScriptContextPtr context, 172 const std::string &name, ScriptParams *params) 173 { 174 std::shared_ptr<ErrorValue> error = std::make_shared<ErrorValue>(USCRIPT_ERROR_INTERPRET); 175 std::shared_ptr<ReturnValue> retValue = std::make_shared<ReturnValue>(); 176 INTERPRETER_LOGI(*this, context, "ExecuteNativeFunc::Execute %s ", name.c_str()); 177 UScriptInstruction* instruction = scriptManager_->FindInstruction(name); 178 if (instruction == nullptr) { 179 USCRIPT_LOGE("Fail to find instruction %s", name.c_str()); 180 return error; 181 } 182 183 std::shared_ptr<UScriptInstructionContext> funcContext = std::make_shared<UScriptInstructionContext>(); 184 if (funcContext == nullptr) { 185 USCRIPT_LOGE("Fail to create context %s", name.c_str()); 186 return error; 187 } 188 if (params == nullptr) { 189 int32_t ret = instruction->Execute(*scriptManager_->GetScriptEnv(name), *funcContext.get()); 190 if (ret != USCRIPT_SUCCESS) { 191 error->SetValue(ret); 192 return error; 193 } 194 retValue->AddValues(funcContext->GetOutVar()); 195 INTERPRETER_LOGI(*this, context, "ExecuteNativeFunc::Execute %s result: %d", name.c_str(), ret); 196 return retValue; 197 } 198 199 for (auto id : params->GetParams()) { 200 UScriptValuePtr result = id->Execute(*this, context); 201 if (result == nullptr || result->GetValueType() == UScriptValue::VALUE_TYPE_ERROR) { 202 INTERPRETER_LOGI(*this, context, "ExecuteNativeFunc::Execute %s ", name.c_str()); 203 return error; 204 } 205 206 if (result->GetValueType() != UScriptValue::VALUE_TYPE_LIST) { 207 funcContext->AddInputParam(result); 208 } else { 209 ReturnValue* values = (ReturnValue*)(result.get()); 210 for (auto out : values->GetValues()) { 211 funcContext->AddInputParam(out); 212 } 213 } 214 } 215 216 int32_t ret = instruction->Execute(*scriptManager_->GetScriptEnv(name), *funcContext.get()); 217 INTERPRETER_LOGI(*this, context, "ExecuteNativeFunc::Execute %s result: %d", name.c_str(), ret); 218 if (ret != USCRIPT_SUCCESS) { 219 error->SetValue(ret); 220 return error; 221 } 222 retValue->AddValues(funcContext->GetOutVar()); 223 return retValue; 224 } 225 } // namespace Uscript 226