how does an interpreter use machine instructions? - interpreter

I have found somewhere on the net the line saying "An Interpreter is a program that implements or simulates a virtual machine using the base set of instructions of a programming language as its machine language. " In this context of the above quote,can anyone explain it as how an interpreter actually accomplish execution of the high level instructions? The tutorials found on the net deals only with abstract manner saying that it takes one line at a time and executes.Does it uses a library of machine instructions or how? I am eager to know about it.

An interpreter looks at each instruction in the source code and then runs code to perform that instruction. It doesn't concern itself with machine code.
For example, if your interpreter is written in C#, and the source code says to add two to a number, the interpreter would eventually call a method that adds the numbers.
Many interpreters compile to bytecode. Bytecodes are instructions that can be executed much faster than the original source code can be parsed. So we might end up with the following bytecodes:
1,
7,
2
The interpreter defines what these number means. But we could have the first number be the instruction. In this case, the 1 means to add a number to a variable. The 7 could be an index to the variable that needs to be added to. And the 2 could be the number to be added. So your handler for the add function could look something like this:
if (bytecode[current] == 1)
{
int varId = bytecode[++current];
int value = bytecode[++current];
Variables[varId] += value;
}
So the machine code is generated by the C# compiler. The interpreter code doesn't care about machine code. It just has a routine to execute the particular instruction.
This should also demonstrate why compiled code runs faster. Instead of bytecode, it would be compiled to machine code. So there is no need to call a handler at runtime. It would simple execute the instructions directly.

Related

Cannot use my gain block from the example. How to?

I am trying to make a custom block for my x310 and use it.
So far, I'm stuck at the example FPGA image compilation because I can't use the custom block gain.
I've followed step by step the "Building an FPGA Image with OOT Blocks" tutorial and successfully compiled and uploaded the image to my x310. A uhd_usrp_probe returned the expected "0/Block#0" linked back and forth to the SEP4 Block. But a warning from RFNOC:BLOCK_FACTORY states "could not find block with Noc-ID 0xb16, 0xffff"
I proceeded anyway after compiling a custom C++ program based on the rfnoc_radio_loopback example in order to make use of the gain block,
I added this line in the includes:
#include <rfnoc::gain::gain_block_control.hpp>
And these two lines after the radio_block_control instancing:
uhd::rfnoc::block_id_t gain_id(0, "Block", 0);
rfnoc::example::gain_block_control::sptr gain_ctrl = graph->get_block<rfnoc::example::gain_block_control>(gain_id);
The program compiles fine but running it returns a LookupError stating "This device doesn't have a block of type rfnoc::example::gain_block_control with ID: 0/Block#0"
I tend to believe the lookup error is clear but I don't know what to do instead.
I first tried to use the block with gnuradio-companion but was not able to generate the block at all. I am sure I am missing something but I have no idea what (apart from actual brain cells).
What is wrong with my C++?
Is it possible to generate a gain block in gnuradio-companion and if yes how?
Do you know of some tutorial that explains the different procedures on how to use a custom block?
There is an example application (rfnoc-example/apps/init_gain_block.cpp) that will test the functionality of the block for you. You can compile/run that to see if your block is working.
If you are seeing uhd_usrp_probe return 0/Block#0 instead of 0/Gain#0, then the .so file is not being picked up properly. The easiest way to test this is to LD_PRELOAD the DLL like this:
LD_PRELOAD=/path/to/librfnoc-example.so uhd_usrp_probe
What this will do is force a preload of the DLL containing the block controller (which will make sure it is registered). You should be seing 0/Gain#0 as the block ID now.

JVM step by step simulator

Is there a free JVM implementation that allow to see the content of the different parts of the Java Virtual Machine (e.g., callstack, heap) and execute a program step by step?
Once the JIT compiles the bytecode to native code, the VM registers and stack have little meaning.
I would use your debugger to see what the Java program is doing line by line. The bytecode is for a virtual machine, not an actual one and the JVM doesn't have to follow the VM literally, only what the program does.
The JIT can
use the many registers your CPU has rather than use a pure stack.
inline code rather than perform method calls.
remove code which it determines isn't used.
place objects on the stack.
not synchronize objects which are only used in a local method.
A good tool to see how the code is translated from byte code to machine code is JITWatch

Scripting Language with "edit and continue" or "hot swap" support? ( Maybe possible in Lua?)

I am making my existing .Net Application Scriptable for non programming users. I added lua, it works like a charm. Then I added debug functionality(pause/continue/step) via debug.sethook. It works also like a charm.
Now I realize that my Application needs edit and continue feature like Visual Studio has it. You pause the execution can edit the code and then continue from your current state with changes applied. This feature is very important to me. I thought this would be easy to do for scripting languages.
Everywhere I read that scripting languages can do this. But even after spending hours of searching I haven't found an Lua implementation yet. It hasn't to be Lua but hot swapping code in Lua would be my first choice.
How can the ability for the user be offered to pause and edit the script and than continue the execution with changes applied?
NOTE: It doesn't have to be Lua every scripting language would be okay
Update
#Schollii
Here is an example:
function doOnX()
if getValue() == "200" then
value = getCalculation()
doSomething() -- many function calls, each can take about 2s
doSomething()
doSomething()
print(value)
doX(value)
end
end
doOnX()
Thank you for your suggestions. This is how it might work:
I will use https://github.com/frabert/NetLua Its a very cool, well written 100% C# Lua Interpreter. It is generating an AST tree first and then directly executing it.
The parser needs to be modified. In Parser.cs public Ast.Block ParseString(string Chunk) there is a parseTree generated first. parseTree.tokens[i].locations are containing the exact position of each token. The Irony.Parsing.ParseTree is then parsed again and is converted to a NetLua.Ast.Block but the location information is missed. I will need to change that so later I will know which Statement is in which line.
Now each Statement from the AST tree is directly executed via EvalBlock. Debug functionality (like I have in my C Binding lua Interpreter DynamicLua via debug.setHook) needs to be added. This can be done in LuaInterpreter.cs internal static LuaArguments EvalBlock(`. Pause/continue/step functions should be no problem. I also can now add current line Highlighting because each statement contains position line information.
When the execution is paused and the code was edited the current LuaContxct is saved. It contains all variables. Also the last Statement with the last execution line is saved.
Now the code String is parsed again to a new AST tree. It gets executed. But all statements are skipped until the saved statement with the line statement is reached. The saved LuaContext is restored and execution can continue with all changes applied.
New variables could be also added after the last executed line, because a new NetLua.Ast.Assignment Statement could just add a new variable to the current LuaContext and everything should just work fine.
Will this work?
I think this is quite challenging and triicky to do right.
Probably the only way you could do that is if you recompile the chunk of code completely. In a function this would mean the whole function regardless of where edit is in function. Then call the function again. Clearly the function must be re-entrant else its side effects (like having incremented a global or upvalue) would have to be undone which isn't possible. If it is not reentrant it will still work just not give expected results (for example if the function increments a global variable by 1 calling it again will result in the global variable having been increased by 2 once the function finally returns).
But finding the lines in the script where the chunknstarts and ends would be tricky if truly generic solution. For specific solution you would have to post specific examples of scripts you want to run and examples of lines you would want to edit. If the whole user script gets recompiled and rerun then this is not a problem, but the side effects is still an issue, examples could help there too.

Don't Both JIT and non-JIT enabled Interpreters Ultimately Produce Machine Code

Ok, I have read several discussions regarding the differences between JIT and non-JIT enabled interpreters, and why JIT usually boosts performance.
However, my question is:
Ultimately, doesn't a non-JIT enabled interpreter have to turn bytecode (line by line) into machine/native code to be executed, just like a JIT compiler will do? I've seen posts and textbooks that say it does, and posts that say it does not. The latter argument is that the interpreter/JVM executes this bytecode directly with no interaction with machine/native code.
If non-JIT interpreters do turn each line into machine code, it seems that the primary benefits of JIT are...
The intelligence of caching either all (normal JIT) or frequently encountered (hotspot/adaptive optimization) parts of the bytecode so that the machine code compilation step is not needed every time.
Any optimization JIT compilers can perform in translating bytecode into machine code.
Is that accurate? There seems to be little difference (other than possible optimization, or JITting blocks vs line by line maybe) between the translation of bytecode to machine code via non-JIT and JIT enabled interpreters.
Thanks in advance.
A non-JIT interpreter doesn't convert bytecode to machine code. You can imagine the workings of a non-JIT bytecode interpreter something like this (I'll use a Java-like pseudocode):
int[] bytecodes = { ... };
int ip = 0; // instruction pointer
while(true) {
int code = bytecodes[ip];
switch(code) {
case 0;
// do something
ip += 1; break;
case 1:
// do something else
ip += 1; break;
// and so on...
}
}
So for every bytecode executed, the interpreter has to retrieve the code, switch on its value to decide what to do, and increment its "instruction pointer" before going to the next iteration.
With a JIT, all that overhead would be reduced to nothing. It would just take the contents of the appropriate switch branches (the parts that say "// do something"), string them together in memory, and execute a jump to the beginning of the first one. No software "instruction pointer" would be required -- only the CPU's hardware instruction pointer. No retrieving of bytecodes from memory and switching on their values either.
Writing a virtual machine is not difficult (if it doesn't have to be extremely high performance), and can be an interesting exercise. I did one once for an embedded project where the program code had to be very compact.
Decades ago, there seemed to be a widespread belief that compilers would turn an entire program into machine code, while interpreters would translate a statement into machine code, execute it, discard it, translate the next one, etc. That notion was 99% incorrect, but there were two a tiny kernels of truth to it. On some microprocessors, some instructions required the use of addresses that were specified in code. For example, on the 8080, there was an instruction to read or write a specified I/O address 0x00-0xFF, but there was no instruction to read-or write an I/O address specified in a register. It was common for language interpreters, if user code did something like "out 123,45", to store into three bytes of memory the instructions "out 7Bh/ret", load the accumulator with 2Dh, and make a call to the first of those instructions. In that situation, the interpreter would indeed be producing a machine code instruction to execute the interpreted instruction. Such code generation, however, was mostly limited to things like IN and OUT instructions.
Many common Microsoft BASIC interpreters for the 6502 (and perhaps the 8080 as well) made somewhat more extensive use of code stored in RAM, but the code that was stored in RAM not not significantly depend upon the program that was executing; the majority of the RAM routine would not change during program execution, but the address of the next instruction was kept in-line as part of the routine allowing the use of an absolute-mode "LDA" instruction, which saved at least one cycle off every byte fetch.

Why is there no main() function in vxWorks?

When using vxWorks as a development platform, we can't write our application with the standard main() function. Why can't we have a main function?
Before the 6.0 version VxWorks only
supported kernel execution environment for tasks and did not support
processes, which is the traditional application execution environment
on OS like Unix or Windows. Tasks have an entry point which is the
address of the code to execute as a task. This address corresponds to
a C or assembly function. It can be a symbol named "main" but there
are C/C++ language assumptions about the main() function that are not
supported in the kernel environment (in particular the traditional
handling of the argc and argv parameters). Furthermore, prior to
VxWorks 6.0, all tasks execute kernel code. You can picture the kernel
as a common repository of code all linked together and then you'll see
that you cannot have several symbols of the same name ("main") since
this would create name collisions.
Now this is accurate only if you link your application code to the
kernel image. If you were to download your application code then the
module loader will accept to load several modules each with a main()
routine. However the last "main" symbol registered in the system
symbol table is the only one you can access via the target shell. If
you want to start tasks executing the code of one of the first loaded
modules you'd have to use the addresses of the previous main()
function. This is possible but not convenient. It is far more
practical to give different names to the entry points of tasks (may be
like "xxxStart" where "xxx" is a name meaningful for what the task is
supposed to do).
Starting with VxWorks 6.0 the OS supports a process environment. This
means, among many other things, that you can have a traditional main()
routine and that its argc and argv parameters are properly handled,
and that the application code is executing in a context (user context)
which is different from the kernel context, thus ensuring the
isolation between application code (which can be flaky) and kernel
code (which is not supposed to be flaky).
PAD