Skip to content

Enable passing of arguments to the polyglot engine#10

Merged
smarr merged 17 commits intooracle:masterfrom
smarr:feature/add-arguments-to-polyglot-engine
Jan 28, 2016
Merged

Enable passing of arguments to the polyglot engine#10
smarr merged 17 commits intooracle:masterfrom
smarr:feature/add-arguments-to-polyglot-engine

Conversation

@smarr
Copy link
Copy Markdown
Contributor

@smarr smarr commented Jan 21, 2016

This change allows to pass an array of strings to the polyglot engine and retrieve it in the environment object.

The goal is to provide a straight-forward way to pass implementation-level arguments, as the typically come from the command line to the PolyglotEngine and the languages.

At the moment, we need to jump through many many hoops.
To realize the same effect, in a language-specific way, it seems we need to do roughly the following:

  1. we need some wrapper class to be able to get to the value later on in the language:

    public static class CmdArgWrapper<T> implements TruffleObject {
      private final T obj;
      public CmdArgWrapper(final T obj) {
        this.obj = obj;
      }
    
      public T getObject() {
        return obj;
      }
    
      @Override
      public ForeignAccess getForeignAccess() {
        throw new UnsupportedOperationException();
      }
    }
  2. we need to pass the arguments to the engine. In the case of SOM, I need these arguments when creating the language context, because the context contains the object system, which depends on the source to be used. And, might also have instruments that need to be configured from the very start.

    String[] args = new String[] {"--kernel", "Kernel.som", "--instrument", "dyn-metrics"};
    Builder builder = PolyglotEngine.newBuilder();
    builder.globalSymbol("CMD_ARGS", new CmdArgWrapper<String[]>(args));
    PolyglotEngine vm = builder.build();

    I believe, the whole notion of global TruffleObjects does not apply here because these arguments are strictly at the implementation level and not language-level objects. But even if there are arguments that become visible to the language, it is the languages job to figure that out and do the necessary wrapping.

  3. in the TruffleLanguage.createContext(...) method, I need to do this:

protected VM createContext(final Env env) {
    Object argsObj = env.importSymbol("CMD_ARGS");
    String[] args = null;
    if (argsObj instanceof CmdArgWrapper<?>) {
      @SuppressWarnings("unchecked")
      CmdArgWrapper<String[]> argsWrapper = (CmdArgWrapper<String[]>) argsObj;
      args = argsWrapper.getObject();
    }
    assert args != null;
  // ...

All this is non-trivial for a very basic use case that any practical language would want to support: take some parameters to control its initialization process/startup.

With the provided patch, all this shrinks to:

String[] args = new String[] {"--kernel", "Kernel.som", "--instrument", "dyn-metrics"};
Builder builder = PolyglotEngine.newBuilder();
builder.setArguments(args);
PolyglotEngine vm = builder.build();

protected VM createContext(final Env env) {
    String[] args = env.getArguments();
// ...

I hope this is compelling enough for inclusion. I know the API should be minimal, but this is a super basic use case, and while there might be static-state solutions that are shorter than this, I believe we should provide an API that allows users to do 'the right thing' easily.

I am not entirely sure about my patch thought. The whole code based involved here is extremely complex and rather hard to comprehend. I mean, it adds about 40 lines of code for something very very trivial: another field + getter. I did not expect that much change for this simple feature.

@smarr smarr added the feature label Jan 21, 2016
@eregon
Copy link
Copy Markdown
Contributor

eregon commented Jan 22, 2016

Is Env per-language?
If so, we just need a way to add the arguments to the proper Env I think.

@smarr
Copy link
Copy Markdown
Contributor Author

smarr commented Jan 22, 2016

The env object references a specific language yes. But the arguments API I added does not take that into account currently. I'll draft something that allows one to specify the language the arguments should belong to, as well.

@smarr
Copy link
Copy Markdown
Contributor Author

smarr commented Jan 22, 2016

Ehm, I don't see how that could be working. To be able to construct a global object, I need to have the language initialized, no?

So, I would propose:

Builder builder = PolyglotEngine.newBuilder();
builder.setArguments(Language1.class, args1);
builder.setArguments(Language2.class, args2);

And then, the following would provide me with the correct argsN:

protected VM createContext(final Env env) {
    String[] args = env.getArguments();

I need the arguments in createContext(.), and I don't want to hack around it.

@smarr
Copy link
Copy Markdown
Contributor Author

smarr commented Jan 22, 2016

This is now implemented in the last commit.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alas, I don't think people should reference the implementation class of a language. They certainly don't have to do so now. Probably the language should be identified by a MIME type.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, used the MIME type. What's the reason for this? Potential class loading issues or something? Intuitively, I would assume that this kind of interaction still happens in tightly bound places, like a main method or something similar. You envision a more dynamic and modular use case?

@woess
Copy link
Copy Markdown
Member

woess commented Jan 22, 2016

Isn't the actual problem here that you can't get global symbol values back out without wrapper?

@smarr smarr force-pushed the feature/add-arguments-to-polyglot-engine branch from 2c6db24 to d94f404 Compare January 22, 2016 14:09
@smarr
Copy link
Copy Markdown
Contributor Author

smarr commented Jan 22, 2016

I think there are two separate concepts here:

  1. Such arguments/parameters as I propose to introduce are on the implementation level, this is data a language runtime might need for initialization.
  2. Global Symbols/Values are language-level objects that are used by an application. As such, I agree with the current design. Actually, I even consider the whole notion of unboxing on those value problematic (for primitives there is a use cases yes). Generally, this is something a specific language knows how to handle and deal with. This is for applications.

So, I would argue we need this second way for implementation-level purpose only to pass data to a language implementation. Unifying these two ways does not seem the right solution for me, because this weakens the nice semantic properties we got for interop.

@woess
Copy link
Copy Markdown
Member

woess commented Jan 22, 2016

@smarr: Good point. I was thinking that perhaps one might want to pass something else than a String[] which is already possible with a global symbol; but I agree it's not the right tool.

@smarr
Copy link
Copy Markdown
Contributor Author

smarr commented Jan 22, 2016

hm, yeah, I was only briefly thinking of other things than strings. Perhaps it should be just Object instead of String[]? My current use case is really typical command line arguments. But, other languages also need access to environment variables from the host system. So, perhaps this should be more general.

@jtulach
Copy link
Copy Markdown
Contributor

jtulach commented Jan 22, 2016

Right, this is the kind of discussion that lead me to believe there shouldn't be any generic setArguments. The languages may have different needs and it should be up to them to decide what data and in what format they want.

I've created #11 to demonstrate how (simple) it feel to access array of parameters in current API.

@smarr
Copy link
Copy Markdown
Contributor Author

smarr commented Jan 22, 2016

Ok, well, so there is at least one lesson we should learn from this. The current API is absolutely not discoverable, and the implementation is way to involved to get any idea of intentions. I am really suffering over here :(

In your version #11, making the jump from TruffleObject to JavaInterop.asJavaObject(.) is just something that is not discoverable. Not sure how much documentation is going to do about that.

@jtulach
Copy link
Copy Markdown
Contributor

jtulach commented Jan 22, 2016

I have a bug in codesnippets that I will fix on Monday. Then we will see...

Right. The trick isn't easy to discover and that's the reason it took me so long and I had to test it first.

@smarr
Copy link
Copy Markdown
Contributor Author

smarr commented Jan 23, 2016

Taking Andreas' comment into account, I generalized the String[] to an Object. Benefits of this vs. the Java Interop based approach:

  • does not require reflection
  • is a separate mechanism for implementation-level data
  • might be easer to find for new users

@jtulach
Copy link
Copy Markdown
Contributor

jtulach commented Jan 25, 2016

Object == the JVM style of typing things. I don't like it.

I've closed the #10 request, because I realized that in this case we don't want to wrap Java types into TruffleObject. Thus we need different method. Rather than setArguments, I'd however prefer:

Builder Builder.config(String mimeType, String key, Object value);
Map<String,Object> Env.getConfig();

I think this would work for your usecase as well and gives languages a chance to expose just names, not real objects.

@smarr
Copy link
Copy Markdown
Contributor Author

smarr commented Jan 25, 2016

@jtulach I added the change to have the API structure like this:

Builder Builder.config(String mimeType, String key, Object value);
Map<String,Object> Env.getConfig(); // can be called from createContext(), value is not wrapped

At the other languages (@woess, @ansalond, @eregon, @chrisseaton, @lukasstadler, @chumer), does this look useful/sufficient to you?

@jtulach
Copy link
Copy Markdown
Contributor

jtulach commented Jan 25, 2016

We should improve our workflow. I've just added implementation of my request too: jtulach@32d4240

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this broken? I am getting exceptions from here. I suggest to use my version of the test - it uses just public methods.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, will change the test. Do you have any strong opinions on the Map<> vs. List<> difference between my and your implementation?

@smarr
Copy link
Copy Markdown
Contributor Author

smarr commented Jan 25, 2016

Hm, ok, since I started the pull request, I assumed it to be my responsibility to fix the issues.

@smarr smarr force-pushed the feature/add-arguments-to-polyglot-engine branch from 03fe3f9 to c837c70 Compare January 25, 2016 15:58
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is any use for two levels of the map. Just merge values for all mimetypes of a language together into one map.

@smarr
Copy link
Copy Markdown
Contributor Author

smarr commented Jan 26, 2016

For documentation: some discussion on the relationship between MIME types and config options: jtulach@32d4240#commitcomment-15653479

@smarr
Copy link
Copy Markdown
Contributor Author

smarr commented Jan 27, 2016

Ok, the latest change merges the per-mime-type options to per-language options from the view of the languages.

Anything else left to do before a merge can be done? (at some point, I'll rebase the change set again on master)

@jtulach
Copy link
Copy Markdown
Contributor

jtulach commented Jan 27, 2016

If you could use the codesnippet tag to enrich Javadoc of the two new methods with real sample, it would be great. Then I am ready to merge.

@smarr
Copy link
Copy Markdown
Contributor Author

smarr commented Jan 27, 2016

Hm, perhaps this is me being lazy, but code examples for getter/setter methods? I mean, the javadoc references the two elements that belong together, which is very helpful. Don't know but code example feel too much here.

@jtulach
Copy link
Copy Markdown
Contributor

jtulach commented Jan 28, 2016

OK. I'll do it myself and merge.

@jtulach
Copy link
Copy Markdown
Contributor

jtulach commented Jan 28, 2016

Here is the state I am OK with: jtulach@f4756bf - can you pull the changeset and push it into your repository so we can reuse this pull request or shall I start a new one?

smarr and others added 16 commits January 28, 2016 15:29
This change allows to pass an array of strings to the polyglot engine and retrieve it in the enviroment object.

Signed-off-by: Stefan Marr <git@stefan-marr.de>
Signed-off-by: Stefan Marr <git@stefan-marr.de>
Not sure what the technical reason is, perhaps to avoid class loading issues? These things seem still to be tightly coupled.

Signed-off-by: Stefan Marr <git@stefan-marr.de>
This enables the languages to use for instance configuration objects and other structured data to represent initialization information.

Signed-off-by: Stefan Marr <git@stefan-marr.de>
This allows the languages to structure their configuration based on different keys in a map.

Signed-off-by: Stefan Marr <git@stefan-marr.de>
Adopted from jtulach@32d4240

Signed-off-by: Stefan Marr <git@stefan-marr.de>
Signed-off-by: Stefan Marr <git@stefan-marr.de>
Signed-off-by: Stefan Marr <git@stefan-marr.de>
Based on comments by @jtulach.

Signed-off-by: Stefan Marr <git@stefan-marr.de>
This change merges the configuration options per language.
Thus, if a language is associated with multiple mime types, it will see a merged map of configurations from these mime types.

Signed-off-by: Stefan Marr <git@stefan-marr.de>
…eter use-case that initiated introduction of the config and getConfig methods.
@smarr smarr force-pushed the feature/add-arguments-to-polyglot-engine branch from 2fe28bf to 752a346 Compare January 28, 2016 14:32
Signed-off-by: Stefan Marr <git@stefan-marr.de>
smarr added a commit that referenced this pull request Jan 28, 2016
…ngine

Enable passing of arguments to the polyglot engine
@smarr smarr merged commit 23a33e8 into oracle:master Jan 28, 2016
@smarr smarr deleted the feature/add-arguments-to-polyglot-engine branch January 28, 2016 14:55
dougxc pushed a commit that referenced this pull request Apr 11, 2016
…truffle:RelativeAndGlobalMX to master

* commit 'f91c754ade0e67b399c5fb8bad3a09839ca7496e':
  If the local, relative mx can't be found, use the one from global PATH
kipply added a commit to Shopify/graal that referenced this pull request Apr 16, 2020
tiainen added a commit to tiainen/graal that referenced this pull request Jan 18, 2022
* add matrix for building both 11 and 17

* fix matrix syntax

* setup jdk

* override jdk with labs jdk

* fix zip paths and JAVA_HOME
jerboaa pushed a commit to jerboaa/graal that referenced this pull request Aug 29, 2024
Backport: Allow custom constructors for arrays and enums
jerboaa added a commit to jerboaa/graal that referenced this pull request Feb 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants