Demystifying Dart: Execution Thread & Dart Call Stack
Tags: dart, flutter, opensource, programming
Published: 2022-09-06 18:20:25


In this series, we will be deep diving into the world of Dart Programming Language; how it works behind the scenes, and why it works in a specific way. 

![Header Image](https://cdn-images-1.medium.com/max/5300/1*QCajckOeBhRaLzi0RoFqig.png)

Let’s start with a brief introduction of Dart Langauge. Dart is a multi-purpose static-typed programming language that is developed by Google. It was first released back in 2013 with version 1.0 coming out before it was used internally within Google to create web, servers, and Mobile Applications. Dart is an object-oriented, garbage-collected language with its syntax very much similar to C. Today, it’s very widely used in conjunction with Flutter to create beautiful-looking [*Mobile*](https://flutter.dev/multi-platform/mobile), [*Web*](https://flutter.dev/multi-platform/web), and [*desktop* ](https://flutter.dev/multi-platform/desktop)applications.

[Dart](https://dart.dev/), like many other programming languages, is a single-threaded language which means it can only run one thing at a time. It executes the code line by line which is also called Thread of Execution.

To understand how Thread of Execution works, Let’s understand it with the help of an example.

![Thread of Execution Example Code](https://cdn-images-1.medium.com/max/2592/1*VZ7E1lJg0ee8BiG5i4MoIw.png)

Before jumping onto the complex (relatively) part, let’s understand the code very quickly. In this code, we have two integers variables and two functions: One for multiplying the two numbers and one for taking the square of a number.

Now let’s understand how Thread of Execution will work. We already know that the main function is our starting point so the code execution will start from there.

![Dart Execution Threads: Initializing the variab](https://cdn-images-1.medium.com/max/2000/1*JOTY4kJE3jiRXiH_N5AKnQ.png)

Firstly, It will initialize the two variables: *firstNumber* and *secondNumber* in what’s known as global memory.

![Dart Thread of Execution: Global Memory](https://cdn-images-1.medium.com/max/2000/1*bUZwjTeWevn75TM6SEZFJQ.png)

Next, there is a function implementation of the *multiply* function:

![Dart Execution Threads: Multiply Function Implementation](https://cdn-images-1.medium.com/max/2000/1*7tQpj94-Cn-hdXSJCWeNdQ.png)

For this part, Dart will take the entire chunk of the code of the function and store it in the memory something like this:

![Dart Thread of Execution: Global Memory](https://cdn-images-1.medium.com/max/2000/1*Ta9A1pHeLezKN-9hWJAQKQ.png)

Moving line by line, similar to the *multiply* function implementation:

![Dart Execution Threads: Square Function Implementation](https://cdn-images-1.medium.com/max/2000/1*0nFDNk8AinsKmSMP2zS65A.png)

Dart will do the same for the *square* function and store it in the global memory something like this:

![Dart Thread of Execution: Global Memory](https://cdn-images-1.medium.com/max/2000/1*x6vVT8NelzrCnIZ7_ZMzzg.png)

Now as per Thread of Execution, Dart will move to the next line in which the variable *multiplyResult* is calling a function.

![Dart Execution Threads: multiply Function Call](https://cdn-images-1.medium.com/max/2592/1*C737N5T51rq6JaAN46zLxg.png)

Here, since Dart cannot initialize this directly, it will create something which is known as the **Dart Execution Thread**. A *Dart Execution Thread* has its own local memory and set of executions. Something like this:

![Dart Execution Thread in Action](https://cdn-images-1.medium.com/max/2006/1*ZB3VU5k-kyjZYV3GbKGcpw.png)

The Dart Execution Thread will execute the entire function body and will return back the value to the global memory from where it was initially called.
After the Dart Execution Thread is done with the execution, it will destroy itself.

Likewise, a similar Dart Execution Thread will be created for *square* function:

![Dart Execution Threads: square Function Call](https://cdn-images-1.medium.com/max/2592/1*1nMxLkm4bvAYZ2EODFHorg.png)

Just like the previous Dart Execution Thread, it will return back the value to the place from where it was called in the global memory. Pictorially it will be something like this:

![Dart Execution Thread in Action](https://cdn-images-1.medium.com/max/2542/1*XNW5dynD6KoPFKXh0gKJgQ.png)

Now If we take a step back and observe, we realize that the entire thing in itself is just another **Dart Execution Context** that is being executed to kickstart an application. Just like a normal Dart Execution Context, it had a memory and set of execution from the very start.

![Dart Execution Thread in Action](https://cdn-images-1.medium.com/max/3030/1*eNJcJzs2XrMp6yKn3umwPA.png)

But there’s one mystery yet to be demystified, we know that Dart is a single-threaded language meaning there can only be one Thread of Execution active at any given time so how will Dart know which Thread is to execute in the main Execution Thread?

And that is exactly where the **Dart Call Stack** comes into action. The Call Stack is just like any other stack but this one holds the Threads of Execution that determines which thread will be executed in the Main Thread. Initially, If there is nothing else in the stack, there always is a *main or global* at the bottom of the stack.

![Dart Call Stack](https://cdn-images-1.medium.com/max/2000/1*zJhrGgf1Y_tn58mgjJqrKQ.png)

But as soon as a new Dart Execution Thread is created, the thread is pushed into the Call Stack and after it’s done and destroyed, it will get popped out from the Call Stack too. Let’s visualize that with a diagram:

![Dart Call Stack](https://cdn-images-1.medium.com/max/2000/1*bDk7jGXBf6lo2-AT3TPzrA.png)

Just like this, the other threads will follow the same pattern and will get pushed and pop into the Stack over the course of their working.

![Dart Call Stack](https://cdn-images-1.medium.com/max/2434/1*UkGDKc2zkpe-sTirtEbDZQ.png)

If there are any nested methods, both will be added to the stack and will stay there until they’re done with their working and then they’ll be popped out of the stack respectively. The completion of the methods is identified with the *return* keyword.

That’s all for now Folks! Hoping this would be the first of many in this series. Thanks for reading this article ❤️

Clap 👏 If you learned something new today.

Feel free to post any queries or corrections you think are required ✔
Do leave feedback so I can improve on my content. Thank you! 😃

You can also Follow me on:

* [Github](https://github.com/iizmotabar)

* [Twitter](https://twitter.com/iizmotabar)

**If you’re interested, here are some of my other articles**:
- [**Flutter 3.3: What’s New?**](https://dev.to/iizmotabar/flutter-33-whats-new-3pmb)
- [**Getting Started with Git and Github**](https://dev.to/iizmotabar/getting-started-with-git-and-github-45ik)