1. IL Engineering Library

Forked from Re: string_exec()

katsmeow said...

Which is why i suggested it be converted to IL code or compiled or whatever the wizardry du jour is, and the result inlined (or gosub'd) where it was called. That automatically restricts it to the same scope as the include file and the procedure containing it.

It really sounds like you do not want an eval() function at all. Instead, you want something like http://commons.apache.org/bcel/

Adding functionality to allow Euphoria IL to be directly modified (read&write) live, at run time, is simple enough. Dealing with raw IL is somewhat like dealing with raw Java bytecode (all numbers and no human readable words) - but we already have some tools like the shrouder and eudis which converts between the two. So with some simple changes, you could call the shrouder to compile your Euphoria code into IL, then inject that IL into your running program. This sounds like it'd do exactly what you are asking for, IIUC.

It'd go something like this:

include euphoria/shrouder.e -- new include based on bind.ex 
 
? 0 
sequence newIL = shrouder:shroud("atom a a = 1 ? a") 
integer pos = get_il_current_pos() -- new builtin 
inject_il_at(pos, newIL) -- new builtin 
? 2 

Output:

0 
1 
2 
new topic     » topic index » view message » categorize

2. Re: IL Engineering Library


Oooooooooooo , self modifying code! I've done that too, actually, but in machine code, many years ago. It saved me some 100 bytes of code, it was simply "this is the first time here", and "now we are exiting". It wasn't thread safe, but i very seldom ran multiple threads on the C64.

One small item about that, if it is permanently injected into the existing IL code that's running, the next string, or file, that needs evaluating/executing, likely will not be the same size, so perfectly overwriting it is unlikely. Can the injection operation accomodate different string sizes with each pass thru the code?

Kat

new topic     » goto parent     » topic index » view message » categorize

3. Re: IL Engineering Library

katsmeow said...

One small item about that, if it is permanently injected into the existing IL code that's running, the next string, or file, that needs evaluating/executing, likely will not be the same size, so perfectly overwriting it is unlikely. Can the injection operation accomodate different string sizes with each pass thru the code?

All Euphoria code is turned into IL before any runtime execution of code happens. So by the time the IL operation occurs, there are no more files to be included, and no more passes of code by the byte-code compiler.

Since there are no strings, this concern is not applicable.

new topic     » goto parent     » topic index » view message » categorize

4. Re: IL Engineering Library

jimcbrown said...
katsmeow said...

One small item about that, if it is permanently injected into the existing IL code that's running, the next string, or file, that needs evaluating/executing, likely will not be the same size, so perfectly overwriting it is unlikely. Can the injection operation accomodate different string sizes with each pass thru the code?

All Euphoria code is turned into IL before any runtime execution of code happens. So by the time the IL operation occurs, there are no more files to be included, and no more passes of code by the byte-code compiler.

Since there are no strings, this concern is not applicable.

Given:

string = "atom a\na+=1\n? a" -- 15 bytes 
existing code1 
convert_and_inject(string) 
existing code2 
and then i do
string = getf("c:\\euphoria\\200bytes_of_code.eux") -- 200 bytes 
existing code1 
convert_and_inject(string) 
existing code2 
and then i do do it again
string = "atom a\na+=1\n? a" -- 15 bytes 
existing code1 
convert_and_inject(string) 
existing code2 
and you are saying the string lengths do not matter and files don't exist? What?

The first run thru the code, the conversion and injection of 15 bytes of source is straight forward. But the 2nd time, the previous injected IL is wrong, string is now whatever was in that file, so the effects of the first injection need undoing, or overwriting. In the 3rd case, the 15 bytes won't overwrite the 200 bytes, but that 200 bytes is old and now wrong, and shouldn't be left in place. Yes, i know that the IL code isn't the same size as the source code, but i needed some numbers to toss around. Either a large block, with potentially a lot of NOPs must be allocated between existing code1 and existing code2, or it must be dynamically relocated each time string is IL'd and injected.

I hope i said it correctly this time.

Kat

new topic     » goto parent     » topic index » view message » categorize

5. Re: IL Engineering Library

katsmeow said...

Given:

string = "atom a\na+=1\n? a" -- 15 bytes 
existing code1 
convert_and_inject(string) 
existing code2 
and then i do
string = getf("c:\\euphoria\\200bytes_of_code.eux") -- 200 bytes 
existing code1 
convert_and_inject(string) 
existing code2 
and then i do do it again
string = "atom a\na+=1\n? a" -- 15 bytes 
existing code1 
convert_and_inject(string) 
existing code2 
and you are saying the string lengths do not matter

Yes, i know that the IL code isn't the same size as the source code, but i needed some numbers to toss around.

That's correct. String lengths do not matter, IL code lengths do. Lets assume then that the IL bytecode length is the same as the source code lengths. (This is obviously not true, the IL will be a lot shorter, but calculating the true lengths without a bytecode compiler would be a headache - at least for me.)

katsmeow said...

The first run thru the code, the conversion and injection of 15 bytes of source is straight forward. But the 2nd time, the previous injected IL is wrong, string is now whatever was in that file, so the effects of the first injection need undoing, or overwriting.

Naturally. The programmer has control here and has the ability to choose to overwrite, instead of inserting, IL code. The programmer will also have the ability to delete segments of IL to undo an injection operation.

katsmeow said...

Either a large block, with potentially a lot of NOPs must be allocated between existing code1 and existing code2, or it must be dynamically relocated each time string is IL'd and injected.

Currently, the former is true for the C-based bytecode interpreter. The Eu-based bytecode interpreter (eu.ex) stores the IL in a sequence.

new topic     » goto parent     » topic index » view message » categorize

6. Re: string_exec()

dcuny said...
jimcbrown said...

What I had envisioned includes the ability to modify true top-level code and then re-execute it.

My concern is that you'll effectively be in the middle of the top-level code:

-- this 
string_exec(...) 
-- that 

If I understand your scheme, it would effectively become:

-- this 
string_exec(...) 
-- code generated by string_exec()  <-- code begins re-executing here 
-- that 

Is that correct?

That's effectively what happens in the example I posted, though I don't call it string_exec() anymore. However, I envisioned a greater level of control over this however, in that you could control exactly where the code generated is inserted, and also you could separately control where re-execution begins. They don't have to be the current position or even the same place at all.

dcuny said...
jimcbrown said...
dcuny said...

If the request is allowing self-modifying code, what exactly does that mean? Can a routine be redefined?

Yes.

It seems you can get the same result via routine_id, at a much cheaper cost.

- David

How does one redefine a routine with routine_id() ?

I had envisioned the ability to rewrite the code of a pre-existing routine on the fly, to make it behave completely different.

new topic     » goto parent     » topic index » view message » categorize

7. Re: string_exec()

This makes me think of CA-Realizer, a Basic language of the 90's, which was able to build and run source code dynamically. It was a Windows-based interpreter using IL code as far as I know (I might be wrong).

As a result someone wrote a Realizer interpreter written in CA-Realizer and released it to public domain which hurted the license of this commercial software. It was known as PC-CA2, based on CA-Realizer 2. I built the same self-interpreter for my own usage as a regular licensee. As far as I remember it took less then 100 lines of code.

I still own CA-Realizer 2 which runs even on Seven 64 bits but builds applications with a Windows 95 look. Not very nice today, but it works! It had some kind of Win32Lib included.

Reagrds

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

8. Re: string_exec()

jmduro said...

This makes me think of CA-Realizer, a Basic language of the 90's, which was able to build and run source code dynamically. It was a Windows-based interpreter using IL code as far as I know (I might be wrong).

As a result someone wrote a Realizer interpreter written in CA-Realizer and released it to public domain which hurted the license of this commercial software. It was known as PC-CA2, based on CA-Realizer 2. I built the same self-interpreter for my own usage as a regular licensee. As far as I remember it took less then 100 lines of code.

I still own CA-Realizer 2 which runs even on Seven 64 bits but builds applications with a Windows 95 look. Not very nice today, but it works! It had some kind of Win32Lib included.

Reagrds

Jean-Marc

I cannot find it for sale or download online. It looks like orphanware circa 1996. Any idea how i can get a copy of it to try out?

Kat

new topic     » goto parent     » topic index » view message » categorize

9. Re: IL Engineering Library

I've implemented the low-level part of this. See http://scm.openeuphoria.org/hg/euphoria/rev/e5aa21896e3f

new topic     » goto parent     » topic index » view message » categorize

10. Re: IL Engineering Library

See also http://scm.openeuphoria.org/hg/euphoria/rev/b9cba54d622a for a very primitive demo.

new topic     » goto parent     » topic index » view message » categorize

11. Re: IL Engineering Library

I'm interested in Euphoria's self-modifying code capabilities.

Jim, could you please elaborate a bit further on Euphoria's potential in this area? For instance, in addition to compiling code at runtime and injecting it into the running program, on the fly, could Euphoria also eliminate from memory some parts of bytecode that are no longer needed? Can the routine_id indentification be used for this purpose, to reference the chunks of bytecode to be injected and those to be eliminated?

new topic     » goto parent     » topic index » view message » categorize

12. Re: IL Engineering Library

Rasti said...

I'm interested in Euphoria's self-modifying code capabilities.

Right now, it doesn't really have any... except in the highly experimental branch.

Rasti said...

Jim, could you please elaborate a bit further on Euphoria's potential in this area?

Sure thing, but remember that what's implemented so far is still in the highly experimental phase, and only implemented for the euphoria backend.

Rasti said...

For instance, in addition to compiling code at runtime and injecting it into the running program, on the fly, could Euphoria also eliminate from memory some parts of bytecode that are no longer needed?

This is already implemented in the equals branch as M_DELETE_IL_AT. See http://scm.openeuphoria.org/hg/euphoria/rev/e5aa21896e3f

Rasti said...

Can the routine_id indentification be used for this purpose, so that chunks of bytecode are injected while others are eliminated?

Yes, it could. This is not implemented yet, but in the euphoria backend it's as easy as returning something like SymTab[e_routine[val[a]+1]][S_CODE].

new topic     » goto parent     » topic index » view message » categorize

13. Re: IL Engineering Library

This is impressive. Is that code in the experimental branch already usable? And when are these features likely to be implemented in the main branch? Six months/one year?

new topic     » goto parent     » topic index » view message » categorize

14. Re: IL Engineering Library

Rasti said...

This is impressive. Is that code in the experimental branch already usable?

Depends on what you mean by "usable". smile There is a single, working demo.

Rasti said...

And when are these features likely to be implemented in the main branch? Six months/one year?

Don't know. It's possible that this feature will never get merged in - the purpose of the branch was to provide a playground to try out new ideas and encourage experimentation. It's there to enhance the discussion of what new features should be added, not as a staging ground to handle merging.

There hasn't really been a whole lot of interest from the community in having an IL Engineering Library for Euphoria. No one has even proposed holding a vote on it.

new topic     » goto parent     » topic index » view message » categorize

15. Re: string_exec()

katsmeow said...

I cannot find it for sale or download online. It looks like orphanware circa 1996. Any idea how i can get a copy of it to try out?

Kat

I beg your pardon, Kat. I missed your post. CAR 3.0 is available on Vetusware: http://www.vetusware.com/download/CA%20Realizer%203.0%203.0/?id=6888

Regards

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

16. Re: string_exec()

To build the free interpreter fom the commercial one, it was as simple as this with CA-Realizer 2(first line untested)

SourceFile = QSys(_CmdLine) 
FileOpen(1, SourceFile) 
LOOP 
	IF NOT FileEOF(1) THEN 
		FileRead(1, s) 
	ELSE 
		EXIT LOOP 
	END IF 
	IF Len(s) > 0 THEN 
		EXECUTE s 
	END IF 
END LOOP 
FileClose(1) 

People had just to compile this as an executable to build a new interpreter.

new topic     » goto parent     » topic index » view message » categorize

17. Re: IL Engineering Library

Sorry to quote from a very old (2004) post [1].

"Derek Parnell" said...

You still won't be able to create new routines at runtime and have them execute in the same address space as the application (eg. have them share variables). With using routine-id, you can only deal with routines that already exist at runtime. There is a convoluted method of doing this in WIndows/Linux environments, but it involves compiling a new routine as a shared library (eg. a Windows DLL) at runtime then loading that library, then running the routine - not a pretty method at all.

@Jim: I was wondering, how was your IL Engineering Library able to overcome the limitations mentioned by Derek? And are the new routines created at runtime actually sharing the same address space as the rest of the program?

[1] http://openeuphoria.org/forum/m/68649.wc

new topic     » goto parent     » topic index » view message » categorize

18. Re: IL Engineering Library

Rasti said...

Sorry to quote from a very old (2004) post [1].

"Derek Parnell" said...

You still won't be able to create new routines at runtime and have them execute in the same address space as the application (eg. have them share variables). With using routine-id, you can only deal with routines that already exist at runtime. There is a convoluted method of doing this in WIndows/Linux environments, but it involves compiling a new routine as a shared library (eg. a Windows DLL) at runtime then loading that library, then running the routine - not a pretty method at all.

@Jim: I was wondering, how was your IL Engineering Library able to overcome the limitations mentioned by Derek?

Actually, your quote shows that Derek already knew of a way of overcoming those limitations.

Meanwhile, my example implementation does not support creating new routines at runtime yet. This would require hooking into the routine_id table and stuff, which can be done, but simply has not been implemented yet.

Rasti said...

And are the new routines created at runtime actually sharing the same address space as the rest of the program?

[1] http://openeuphoria.org/forum/m/68649.wc

Yes.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu