diff --git a/kernel/include/kernel/ACPI/AML/IfElse.h b/kernel/include/kernel/ACPI/AML/IfElse.h index 37a09de52d..3d5322b67f 100644 --- a/kernel/include/kernel/ACPI/AML/IfElse.h +++ b/kernel/include/kernel/ACPI/AML/IfElse.h @@ -50,8 +50,8 @@ namespace Kernel::ACPI::AML while (context.aml_data.size() > 0) { auto object_result = AML::parse_object(context); - if (object_result.returned()) - return ParseResult(ParseResult::Result::Returned, object_result.node()); + if (object_result.returned() || object_result.breaked() || object_result.continued()) + return object_result; if (!object_result.success()) return ParseResult::Failure; } diff --git a/kernel/include/kernel/ACPI/AML/Node.h b/kernel/include/kernel/ACPI/AML/Node.h index eb965805a2..09c0cae54b 100644 --- a/kernel/include/kernel/ACPI/AML/Node.h +++ b/kernel/include/kernel/ACPI/AML/Node.h @@ -78,6 +78,8 @@ namespace Kernel::ACPI::AML Success, Failure, Returned, + Breaked, + Continued, }; ParseResult(Result success) @@ -96,6 +98,8 @@ namespace Kernel::ACPI::AML bool success() const { return m_result == Result::Success; } bool returned() const { return m_result == Result::Returned; } + bool breaked() const { return m_result == Result::Breaked; } + bool continued() const { return m_result == Result::Continued; } BAN::RefPtr node() { diff --git a/kernel/include/kernel/ACPI/AML/While.h b/kernel/include/kernel/ACPI/AML/While.h index 2dbfd15ab5..4a770b60f3 100644 --- a/kernel/include/kernel/ACPI/AML/While.h +++ b/kernel/include/kernel/ACPI/AML/While.h @@ -12,9 +12,22 @@ namespace Kernel::ACPI::AML static ParseResult parse(ParseContext& context) { ASSERT(context.aml_data.size() >= 1); - ASSERT(static_cast(context.aml_data[0]) == Byte::WhileOp); + + AML::Byte opcode = static_cast(context.aml_data[0]); context.aml_data = context.aml_data.slice(1); + switch (opcode) + { + case AML::Byte::BreakOp: + return ParseResult(ParseResult::Result::Breaked); + case AML::Byte::ContinueOp: + return ParseResult(ParseResult::Result::Continued); + case AML::Byte::WhileOp: + break; + default: + ASSERT_NOT_REACHED(); + } + auto while_pkg = AML::parse_pkg(context.aml_data); if (!while_pkg.has_value()) return ParseResult::Failure; @@ -43,16 +56,13 @@ namespace Kernel::ACPI::AML while (context.aml_data.size() > 0) { - // NOTE: we can just parse BreakOp here, since this is the only legal place for BreakOp - if (static_cast(context.aml_data[0]) == AML::Byte::BreakOp) - { - context.aml_data = context.aml_data.slice(1); - breaked = true; - break; - } auto object_result = AML::parse_object(context); if (object_result.returned()) return ParseResult(ParseResult::Result::Returned, object_result.node()); + if (object_result.breaked()) + breaked = true; + if (object_result.breaked() || object_result.continued()) + break; if (!object_result.success()) return ParseResult::Failure; } diff --git a/kernel/kernel/ACPI/AML/Node.cpp b/kernel/kernel/ACPI/AML/Node.cpp index 739b31c950..af36b230ef 100644 --- a/kernel/kernel/ACPI/AML/Node.cpp +++ b/kernel/kernel/ACPI/AML/Node.cpp @@ -173,6 +173,8 @@ namespace Kernel::ACPI return AML::Scope::parse(context); case AML::Byte::IfOp: return AML::IfElse::parse(context); + case AML::Byte::BreakOp: + case AML::Byte::ContinueOp: case AML::Byte::WhileOp: return AML::While::parse(context); case AML::Byte::StoreOp: