diff --git a/Import/GacUI.cpp b/Import/GacUI.cpp index 131d0d5a..e5e9ba79 100644 --- a/Import/GacUI.cpp +++ b/Import/GacUI.cpp @@ -33509,6 +33509,31 @@ Native Window Provider { currentController=controller; } + +/*********************************************************************** +Helper Functions +***********************************************************************/ + + INativeCursor* GetCursorFromHitTest(INativeWindowListener::HitTestResult hitTestResult, INativeResourceService* resourceService) + { + switch (hitTestResult) + { + case INativeWindowListener::BorderLeft: + case INativeWindowListener::BorderRight: + return resourceService->GetSystemCursor(INativeCursor::SizeWE); + case INativeWindowListener::BorderTop: + case INativeWindowListener::BorderBottom: + return resourceService->GetSystemCursor(INativeCursor::SizeNS); + case INativeWindowListener::BorderLeftTop: + case INativeWindowListener::BorderRightBottom: + return resourceService->GetSystemCursor(INativeCursor::SizeNWSE); + case INativeWindowListener::BorderRightTop: + case INativeWindowListener::BorderLeftBottom: + return resourceService->GetSystemCursor(INativeCursor::SizeNESW); + default: + return nullptr; + } + } } } @@ -34138,27 +34163,12 @@ GuiHostedController::INativeWindowListener (PreAction) auto x = info.x.value - hoveringWindow->wmWindow.bounds.x1.value; auto y = info.y.value - hoveringWindow->wmWindow.bounds.y1.value; auto hitTestResult = PerformHitTest(From(hoveringWindow->listeners), { {x},{y} }); - switch (hitTestResult) + auto cursor = GetCursorFromHitTest(hitTestResult, ResourceService()); + if (cursor == nullptr) { - case INativeWindowListener::BorderLeft: - case INativeWindowListener::BorderRight: - nativeWindow->SetWindowCursor(ResourceService()->GetSystemCursor(INativeCursor::SizeWE)); - break; - case INativeWindowListener::BorderTop: - case INativeWindowListener::BorderBottom: - nativeWindow->SetWindowCursor(ResourceService()->GetSystemCursor(INativeCursor::SizeNS)); - break; - case INativeWindowListener::BorderLeftTop: - case INativeWindowListener::BorderRightBottom: - nativeWindow->SetWindowCursor(ResourceService()->GetSystemCursor(INativeCursor::SizeNWSE)); - break; - case INativeWindowListener::BorderRightTop: - case INativeWindowListener::BorderLeftBottom: - nativeWindow->SetWindowCursor(ResourceService()->GetSystemCursor(INativeCursor::SizeNESW)); - break; - default: - nativeWindow->SetWindowCursor(hoveringWindow->GetWindowCursor()); + cursor = hoveringWindow->GetWindowCursor(); } + nativeWindow->SetWindowCursor(cursor); } if (wmWindow) diff --git a/Import/GacUI.h b/Import/GacUI.h index 2852ec75..5ce82582 100644 --- a/Import/GacUI.h +++ b/Import/GacUI.h @@ -3280,6 +3280,14 @@ Native Window Controller /// The global native system service controller. extern void SetCurrentController(INativeController* controller); + /// + /// Get a cursor according to the hit test result. + /// + /// The hit test result. + /// The resource service to get cursors. + /// Returns the cursor according to the hit test result. It could return nullptr when the cursor is not defined. + extern INativeCursor* GetCursorFromHitTest(INativeWindowListener::HitTestResult hitTestResult, INativeResourceService* resourceService); + /// /// A helper function calling multiple . /// diff --git a/Import/GacUICompiler.cpp b/Import/GacUICompiler.cpp index 5d4ab887..8935b90f 100644 --- a/Import/GacUICompiler.cpp +++ b/Import/GacUICompiler.cpp @@ -10950,7 +10950,7 @@ GuiWorkflowSharedManagerPlugin { if (!workflowManager) { - workflowManager = Ptr(new WfLexicalScopeManager(workflowParser)); + workflowManager = Ptr(new WfLexicalScopeManager(workflowParser, WfCpuArchitecture::AsExecutable)); } return workflowManager.Obj(); } diff --git a/Import/Vlpp.cpp b/Import/Vlpp.cpp index 5a01aeb7..1d0455f3 100644 --- a/Import/Vlpp.cpp +++ b/Import/Vlpp.cpp @@ -1217,12 +1217,6 @@ UnitTest namespace execution_impl { - struct UnitTestLink - { - const char* fileName; - UnitTestFileProc testProc = nullptr; - UnitTestLink* next = nullptr; - }; UnitTestLink* testHead = nullptr; UnitTestLink** testTail = &testHead; @@ -1383,10 +1377,6 @@ UnitTest } { - auto current = testHead; - testHead = nullptr; - testTail = nullptr; - UnitTestContext context; testContext = &context; totalFiles = 0; @@ -1403,18 +1393,17 @@ UnitTest PrintMessage(L"Failures are not suppressed.", MessageKind::Info); } + auto current = testHead; while (current) { context.failed = false; - PrintMessage(atow(current->fileName), MessageKind::File); + PrintMessage(atow(AString::Unmanaged(current->fileName)), MessageKind::File); context.indentation = L" "; ExecuteAndSuppressFailure(current->testProc); if (!testContext->failed) passedFiles++; totalFiles++; context.indentation = L""; - auto temp = current; current = current->next; - delete temp; } bool passed = totalFiles == passedFiles; @@ -1464,11 +1453,8 @@ UnitTest } } - void UnitTest::RegisterTestFile(const char* fileName, UnitTestFileProc testProc) + void UnitTest::RegisterTestFile(UnitTestLink* link) { - auto link = new UnitTestLink; - link->fileName = fileName; - link->testProc = testProc; *testTail = link; testTail = &link->next; } diff --git a/Import/Vlpp.h b/Import/Vlpp.h index 0a7c73d4..7606554b 100644 --- a/Import/Vlpp.h +++ b/Import/Vlpp.h @@ -7080,36 +7080,90 @@ Quick Sort template void SortLambda(T* items, vint length, F orderer) { - if (length == 0) return; - vint pivot = 0; - vint left = 0; - vint right = 0; - bool flag = false; - - while (left + right + 1 != length) + while (true) { - vint& mine = (flag ? left : right); - vint& theirs = (flag ? right : left); - vint candidate = (flag ? left : length - right - 1); - vint factor = (flag ? -1 : 1); + if (length == 0) return; + vint pivot = 0; + vint left = 0; + vint right = 0; - if (orderer(items[pivot], items[candidate]) * factor <= 0) { - mine++; + bool flag = false; + while (left + right + 1 != length) + { + vint& mine = (flag ? left : right); + vint& theirs = (flag ? right : left); + vint candidate = (flag ? left : length - right - 1); + vint factor = (flag ? -1 : 1); + + if (orderer(items[pivot], items[candidate]) * factor <= 0) + { + mine++; + } + else + { + theirs++; + T temp = items[pivot]; + items[pivot] = items[candidate]; + items[candidate] = temp; + pivot = candidate; + flag = !flag; + } + } + } + + { + vint reading = left - 1; + vint writing = reading; + while (reading >= 0) + { + if (orderer(items[pivot], items[reading]) == 0) + { + if (reading != writing) + { + T temp = items[reading]; + items[reading] = items[writing]; + items[writing] = temp; + } + writing--; + } + reading--; + } + left = writing + 1; + } + + { + vint reading = length - right; + vint writing = reading; + while (reading < length) + { + if (orderer(items[pivot], items[reading]) == 0) + { + if (reading != writing) + { + T temp = items[reading]; + items[reading] = items[writing]; + items[writing] = temp; + } + writing++; + } + reading++; + } + right = length - writing; + } + + if (left < right) + { + SortLambda(items, left, orderer); + items += length - right; + length = right; } else { - theirs++; - T temp = items[pivot]; - items[pivot] = items[candidate]; - items[candidate] = temp; - pivot = candidate; - flag = !flag; + SortLambda(items + length - right, right, orderer); + length = left; } } - - SortLambda(items, left, orderer); - SortLambda(items + left + 1, right, orderer); } /// Quick sort. @@ -8502,6 +8556,13 @@ namespace vl namespace unittest { using UnitTestFileProc = void(*)(); + + struct UnitTestLink + { + const char* fileName = nullptr; + UnitTestFileProc testProc = nullptr; + UnitTestLink* next = nullptr; + }; /// ///

Unit test framework.

@@ -8615,17 +8676,22 @@ namespace vl /// Accept the second argument of the main function. static int RunAndDisposeTests(int argc, char* argv[]); - static void RegisterTestFile(const char* fileName, UnitTestFileProc testProc); + static void RegisterTestFile(UnitTestLink* link); static void RunCategoryOrCase(const WString& description, bool isCategory, Func&& callback); static void EnsureLegalToAssert(); }; class UnitTestFile { + protected: + UnitTestLink link; + public: UnitTestFile(const char* fileName, UnitTestFileProc testProc) { - UnitTest::RegisterTestFile(fileName, testProc); + link.fileName = fileName; + link.testProc = testProc; + UnitTest::RegisterTestFile(&link); } }; diff --git a/Import/VlppWorkflowCompiler.cpp b/Import/VlppWorkflowCompiler.cpp index 1939eb4c..04db8b7d 100644 --- a/Import/VlppWorkflowCompiler.cpp +++ b/Import/VlppWorkflowCompiler.cpp @@ -259,16 +259,26 @@ CheckScopes_CycleDependency }) ); - switch (tds[0]->GetTypeDescriptorFlags()) + auto selectedTd = tds[0]; + for (auto candidateTd : From(tds).Skip(1)) + { + auto selectedRange = visitor.depItems[selectedTd]->codeRange; + auto candidateRange = visitor.depItems[candidateTd]->codeRange; + + if (candidateRange.codeIndex > selectedRange.codeIndex) { selectedTd = candidateTd; continue; } + if (candidateRange.start > selectedRange.start) { selectedTd = candidateTd; continue; } + } + + switch (selectedTd->GetTypeDescriptorFlags()) { case TypeDescriptorFlags::Struct: - manager->errors.Add(WfErrors::StructRecursivelyIncludeItself(dynamic_cast(visitor.depItems[tds[0]]), tds)); + manager->errors.Add(WfErrors::StructRecursivelyIncludeItself(dynamic_cast(visitor.depItems[selectedTd]), tds)); break; case TypeDescriptorFlags::Class: - manager->errors.Add(WfErrors::ClassRecursiveInheritance(dynamic_cast(visitor.depItems[tds[0]]), tds)); + manager->errors.Add(WfErrors::ClassRecursiveInheritance(dynamic_cast(visitor.depItems[selectedTd]), tds)); break; case TypeDescriptorFlags::Interface: - manager->errors.Add(WfErrors::InterfaceRecursiveInheritance(dynamic_cast(visitor.depItems[tds[0]]), tds)); + manager->errors.Add(WfErrors::InterfaceRecursiveInheritance(dynamic_cast(visitor.depItems[selectedTd]), tds)); break; default:; } @@ -668,8 +678,9 @@ ResolveExpressionResult WfLexicalScopeManager ***********************************************************************/ - WfLexicalScopeManager::WfLexicalScopeManager(workflow::Parser& _workflowParser) + WfLexicalScopeManager::WfLexicalScopeManager(workflow::Parser& _workflowParser, WfCpuArchitecture _cpuArchitecture) :workflowParser(_workflowParser) + , cpuArchitecture(_cpuArchitecture) { workflowParserHandler = glr::InstallDefaultErrorMessageGenerator(workflowParser, errors); attributes.Add({ L"cpp", L"File" }, TypeInfoRetriver::CreateTypeInfo()); @@ -677,6 +688,28 @@ WfLexicalScopeManager attributes.Add({ L"cpp", L"Private" }, TypeInfoRetriver::CreateTypeInfo()); attributes.Add({ L"cpp", L"Protected" }, TypeInfoRetriver::CreateTypeInfo()); attributes.Add({ L"cpp", L"Friend" }, TypeInfoRetriver::CreateTypeInfo()); + + switch (cpuArchitecture) + { + case WfCpuArchitecture::x86: + cputdSInt = reflection::description::GetTypeDescriptor(); + cputdUInt = reflection::description::GetTypeDescriptor(); + cputiSInt = reflection::description::TypeInfoRetriver::CreateTypeInfo(); + cputiUInt = reflection::description::TypeInfoRetriver::CreateTypeInfo(); + break; + case WfCpuArchitecture::x64: + cputdSInt = reflection::description::GetTypeDescriptor(); + cputdUInt = reflection::description::GetTypeDescriptor(); + cputiSInt = reflection::description::TypeInfoRetriver::CreateTypeInfo(); + cputiUInt = reflection::description::TypeInfoRetriver::CreateTypeInfo(); + break; + case WfCpuArchitecture::AsExecutable: + cputdSInt = reflection::description::GetTypeDescriptor(); + cputdUInt = reflection::description::GetTypeDescriptor(); + cputiSInt = reflection::description::TypeInfoRetriver::CreateTypeInfo(); + cputiUInt = reflection::description::TypeInfoRetriver::CreateTypeInfo(); + break; + } } WfLexicalScopeManager::~WfLexicalScopeManager() @@ -2553,7 +2586,22 @@ CheckScopes_SymbolType bool CheckScopes_SymbolType(WfLexicalScopeManager* manager) { vint errorCount = manager->errors.Count(); - for (auto scope : manager->nodeScopes.Values()) + for (auto scope : From(manager->nodeScopes) + .OrderBy([](auto&& a, auto&& b) + { + auto rangeA = a.key->codeRange; + auto rangeB = b.key->codeRange; + if (rangeA.codeIndex != rangeB.codeIndex) + { + return rangeA.codeIndex - rangeB.codeIndex; + } + else + { + return glr::ParsingTextPos::Compare(rangeA.start, rangeB.start); + } + }) + .Select([](auto&& pair) { return pair.value; }) + ) { if (!manager->checkedScopes_SymbolType.Contains(scope.Obj())) { @@ -2768,7 +2816,7 @@ CompleteScopeForClassMember } auto& smInfo = manager->stateMachineInfos[node]; - smInfo->createCoroutineMethod->AddParameter(Ptr(new ParameterInfoImpl(smInfo->createCoroutineMethod.Obj(), L"startState", TypeInfoRetriver::CreateTypeInfo()))); + smInfo->createCoroutineMethod->AddParameter(Ptr(new ParameterInfoImpl(smInfo->createCoroutineMethod.Obj(), L"startState", manager->cputiSInt))); smInfo->createCoroutineMethod->SetReturn(TypeInfoRetriver::CreateTypeInfo()); } @@ -3587,6 +3635,21 @@ namespace vl return { node, node->codeRange, message }; } + template + WString ListToErrorMessage(List& items, F&& f) + { + WString description; + for (auto friendlyName : From(items) + .Select(f) + .OrderBy([](auto&& a, auto&& b) { return WString::Compare(a, b); }) + ) + { + description += L"\r\n\t"; + description += friendlyName; + } + return description; + } + /*********************************************************************** WfErrors ***********************************************************************/ @@ -3788,12 +3851,7 @@ WfErrors glr::ParsingError WfErrors::CannotPickOverloadedFunctions(glr::ParsingAstBase* node, collections::List& results) { - WString description; - for (auto [result, index] : indexed(results)) - { - description += L"\r\n\t"; - description += result.GetFriendlyName(); - } + auto description = ListToErrorMessage(results, [](auto&& result) { return result.GetFriendlyName(); }); return MakeParsingError(node, L"A22: Cannot decide which function to call in multiple targets: " + description + L"."); } @@ -3967,12 +4025,7 @@ WfErrors glr::ParsingError WfErrors::CoProviderNotExists(WfCoProviderStatement* node, collections::List& candidates) { - WString description; - for (auto candidate : candidates) - { - description += L"\r\n\t"; - description += candidate; - } + auto description = ListToErrorMessage(candidates, [](auto&& candidate) { return candidate; }); if (node->name.value == L"") { return MakeParsingError(node, L"C9: Cannot find a coroutine provider based on the function return type, all of the following types do not exist: " + description + L"."); @@ -4015,12 +4068,7 @@ WfErrors } else { - WString description; - for (auto type : types) - { - description += L"\r\n\t"; - description += type->GetTypeFriendlyName(); - } + auto description = ListToErrorMessage(types, [](auto&& type) { return type->GetTypeFriendlyName(); }); return MakeParsingError(node, L"C11: Failed to resolve the result type of coroutine operator \"" + operatorName + L"\", no appropriate static function \"CastResult\" is found in the following types. It requires exactly one argument of type \"object\" with a return type which is not \"void\": " + description + L"."); } } @@ -4148,12 +4196,7 @@ WfErrors glr::ParsingError WfErrors::CannotPickOverloadedInterfaceMethods(WfExpression* node, collections::List& results) { - WString description; - for (auto result : results) - { - description += L"\r\n\t"; - description += result.GetFriendlyName(); - } + auto description = ListToErrorMessage(results, [](auto&& result) { return result.GetFriendlyName(); }); return MakeParsingError(node, L"D5: Cannot decide which function to implement in multiple targets:" + description + L"."); } @@ -4224,12 +4267,7 @@ WfErrors glr::ParsingError WfErrors::StructRecursivelyIncludeItself(WfStructDeclaration* node, collections::List& tds) { - WString description; - for (auto td : tds) - { - description += L"\r\n\t"; - description += td->GetTypeName(); - } + auto description = ListToErrorMessage(tds, [](auto&& td) { return td->GetTypeName(); }); return MakeParsingError(node, L"D13: Recursive references are found in these struct definitions:" + description + L"."); } @@ -4285,12 +4323,7 @@ WfErrors glr::ParsingError WfErrors::TooManyTargets(glr::ParsingAstBase* node, collections::List& results, const WString& name) { - WString description; - for (auto [result, index] : indexed(results)) - { - description += L"\r\n\t"; - description += result.GetFriendlyName(); - } + auto description = ListToErrorMessage(results, [](auto&& result) { return result.GetFriendlyName(); }); return MakeParsingError(node, L"F3: Symbol \"" + name + L"\" references to too many targets: " + description + L"."); } @@ -4412,23 +4445,13 @@ WfErrors glr::ParsingError WfErrors::ClassRecursiveInheritance(WfClassDeclaration* node, collections::List& tds) { - WString description; - for (auto td : tds) - { - description += L"\r\n\t"; - description += td->GetTypeName(); - } + auto description = ListToErrorMessage(tds, [](auto&& td) { return td->GetTypeName(); }); return MakeParsingError(node, L"G10: Recursive inheriting are found in these class definitions:" + description + L"."); } glr::ParsingError WfErrors::InterfaceRecursiveInheritance(WfClassDeclaration* node, collections::List& tds) { - WString description; - for (auto td : tds) - { - description += L"\r\n\t"; - description += td->GetTypeName(); - } + auto description = ListToErrorMessage(tds, [](auto&& td) { return td->GetTypeName(); }); return MakeParsingError(node, L"G10: Recursive inheriting are found in these interface definitions:" + description + L"."); } @@ -4459,23 +4482,13 @@ WfErrors glr::ParsingError WfErrors::CppUnableToDecideClassOrder(WfClassDeclaration* node, collections::List& tds) { - WString description; - for (auto td : tds) - { - description += L"\r\n\t"; - description += td->GetTypeName(); - } + auto description = ListToErrorMessage(tds, [](auto&& td) { return td->GetTypeName(); }); return MakeParsingError(node, L"CPP1: (C++ Code Generation) Cannot decide order of the following classes. It is probably caused by inheritance relationships of internal classes inside these classes:" + description + L"."); } glr::ParsingError WfErrors::CppUnableToSeparateCustomFile(WfClassDeclaration* node, collections::List& tds) { - WString description; - for (auto td : tds) - { - description += L"\r\n\t"; - description += td->GetTypeName(); - } + auto description = ListToErrorMessage(tds, [](auto&& td) { return td->GetTypeName(); }); return MakeParsingError(node, L"CPP2: (C++ Code Generation) @cpp:File atrribute values for these classes are invalid. Generating classes to source files specified by these attribute values will create source files which do not compile. It is probably caused by inheritance relationships of internal classes inside these classes:" + description + L"."); } } @@ -7461,7 +7474,7 @@ ExpandNewCoroutineExpression auto varDecl = Ptr(new WfVariableDeclaration); newExpr->declarations.Add(varDecl); varDecl->name.value = L""; - varDecl->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); + varDecl->type = GetTypeFromTypeInfo(manager->cputiSInt.Obj()); auto stateExpr = Ptr(new WfIntegerExpression); stateExpr->value.value = L"0"; @@ -7476,7 +7489,7 @@ ExpandNewCoroutineExpression auto varDecl = Ptr(new WfVariableDeclaration); newExpr->declarations.Add(varDecl); varDecl->name.value = L""; - varDecl->type = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); + varDecl->type = GetTypeFromTypeInfo(manager->cputiSInt.Obj()); varDecl->expression = GenerateCoroutineInvalidId(); } @@ -10289,10 +10302,10 @@ CreateTypeInfoFromType typeDescriptor = description::GetTypeDescriptor(); break; case WfPredefinedTypeName::Int: - typeDescriptor = description::GetTypeDescriptor(); + typeDescriptor = scope->FindManager()->cputdSInt; break; case WfPredefinedTypeName::UInt: - typeDescriptor = description::GetTypeDescriptor(); + typeDescriptor = scope->FindManager()->cputdUInt; break; case WfPredefinedTypeName::Float: typeDescriptor = description::GetTypeDescriptor(); @@ -12497,11 +12510,7 @@ ValidateSemantic(Expression) auto typeDescriptor = expectedType ? expectedType->GetTypeDescriptor() : nullptr; if (!typeDescriptor || typeDescriptor->GetTypeDescriptorFlags() == TypeDescriptorFlags::Object || typeDescriptor==description::GetTypeDescriptor()) { -#ifdef VCZH_64 - typeDescriptor = description::GetTypeDescriptor(); -#else - typeDescriptor = description::GetTypeDescriptor(); -#endif + typeDescriptor = manager->cputdSInt; } if (auto serializableType = typeDescriptor->GetSerializableType()) @@ -12608,24 +12617,24 @@ ValidateSemantic(Expression) ITypeInfo* classType = genericType->GetElementType(); if (classType->GetTypeDescriptor() == description::GetTypeDescriptor()) { - indexType = TypeInfoRetriver::CreateTypeInfo(); + indexType = manager->cputiSInt; resultType = CopyTypeInfo(genericType->GetGenericArgument(0)); } else if (classType->GetTypeDescriptor() == description::GetTypeDescriptor()) { - indexType = TypeInfoRetriver::CreateTypeInfo(); + indexType = manager->cputiSInt; resultType = CopyTypeInfo(genericType->GetGenericArgument(0)); leftValue = true; } else if (classType->GetTypeDescriptor() == description::GetTypeDescriptor()) { - indexType = TypeInfoRetriver::CreateTypeInfo(); + indexType = manager->cputiSInt; resultType = CopyTypeInfo(genericType->GetGenericArgument(0)); leftValue = true; } else if (classType->GetTypeDescriptor() == description::GetTypeDescriptor()) { - indexType = TypeInfoRetriver::CreateTypeInfo(); + indexType = manager->cputiSInt; resultType = CopyTypeInfo(genericType->GetGenericArgument(0)); leftValue = true; } @@ -12649,24 +12658,24 @@ ValidateSemantic(Expression) { if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor()) { - indexType = TypeInfoRetriver::CreateTypeInfo(); + indexType = manager->cputiSInt; resultType = TypeInfoRetriver::CreateTypeInfo(); } else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor()) { - indexType = TypeInfoRetriver::CreateTypeInfo(); + indexType = manager->cputiSInt; resultType = TypeInfoRetriver::CreateTypeInfo(); leftValue = true; } else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor()) { - indexType = TypeInfoRetriver::CreateTypeInfo(); + indexType = manager->cputiSInt; resultType = TypeInfoRetriver::CreateTypeInfo(); leftValue = true; } else if (genericType->GetTypeDescriptor() == description::GetTypeDescriptor()) { - indexType = TypeInfoRetriver::CreateTypeInfo(); + indexType = manager->cputiSInt; resultType = TypeInfoRetriver::CreateTypeInfo(); leftValue = true; } @@ -24394,9 +24403,9 @@ Compile return GenerateAssembly(manager); } - Ptr Compile(workflow::Parser& workflowParser, collections::List& moduleCodes, collections::List& errors) + Ptr Compile(workflow::Parser& workflowParser, analyzer::WfCpuArchitecture cpuArchitecture, collections::List& moduleCodes, collections::List& errors) { - WfLexicalScopeManager manager(workflowParser); + WfLexicalScopeManager manager(workflowParser, cpuArchitecture); return Compile(&manager, moduleCodes, errors); } } @@ -25629,18 +25638,32 @@ GenerateInstructions(Expression) auto result = context.manager->expressionResolvings[node]; auto elementType = Ptr(result.type->GetElementType()->GetGenericArgument(0)); auto type = GetInstructionTypeArgument(elementType); + + WfRuntimeValue one; + switch (context.manager->cpuArchitecture) + { + case WfCpuArchitecture::x86: + one = {(vint32_t)1}; + break; + case WfCpuArchitecture::x64: + one = { (vint64_t)1 }; + break; + default: + one = { (vint)1 }; + break; + } GenerateExpressionInstructions(context, node->begin, elementType); if (node->beginBoundary == WfRangeBoundary::Exclusive) { - INSTRUCTION(Ins::LoadValue({ (vint)1 })); + INSTRUCTION(Ins::LoadValue(one)); INSTRUCTION(Ins::OpAdd(type)); } GenerateExpressionInstructions(context, node->end, elementType); if (node->endBoundary == WfRangeBoundary::Exclusive) { - INSTRUCTION(Ins::LoadValue({ (vint)1 })); + INSTRUCTION(Ins::LoadValue(one)); INSTRUCTION(Ins::OpSub(type)); } diff --git a/Import/VlppWorkflowCompiler.h b/Import/VlppWorkflowCompiler.h index 90916f3f..80abdc80 100644 --- a/Import/VlppWorkflowCompiler.h +++ b/Import/VlppWorkflowCompiler.h @@ -5046,6 +5046,16 @@ Scope Manager collections::Dictionary stateIds; }; + /// + /// CPU architecture + /// + enum class WfCpuArchitecture + { + x86, + x64, + AsExecutable, + }; + /// Scope manager for storing all information generated from Workflow modules during compiling. class WfLexicalScopeManager : public Object { @@ -5089,6 +5099,12 @@ Scope Manager vint usedCodeIndex = 0; public: + WfCpuArchitecture cpuArchitecture = WfCpuArchitecture::AsExecutable; + ITypeDescriptor* cputdSInt = nullptr; + ITypeDescriptor* cputdUInt = nullptr; + Ptr cputiSInt; + Ptr cputiUInt; + workflow::Parser& workflowParser; Ptr workflowParserHandler; AttributeTypeMap attributes; @@ -5122,7 +5138,8 @@ Scope Manager /// Create a Workflow compiler. /// The workflow parser table. It can be retrived from [M:vl.workflow.WfLoadTable]. - WfLexicalScopeManager(workflow::Parser& _workflowParser); + /// The target CPU architecture. + WfLexicalScopeManager(workflow::Parser& _workflowParser, WfCpuArchitecture _cpuArchitecture); ~WfLexicalScopeManager(); /// Add a Workflow module. Syntax errors can be found at . @@ -5695,9 +5712,10 @@ Code Generation /// Compile a Workflow program. Use the other one whenever possible, which alloes reusing to improve performance. /// The generated assembly. Return nullptr if failed to compile. /// The generated parser class. + /// The target CPU architecture. /// All workflow module codes. /// Container to get all errors generated during compiling. - extern Ptr Compile(workflow::Parser& workflowParser, collections::List& moduleCodes, collections::List& errors); + extern Ptr Compile(workflow::Parser& workflowParser, analyzer::WfCpuArchitecture cpuArchitecture, collections::List& moduleCodes, collections::List& errors); } } }