Skip to content

SI-7916: ScriptEngine support#4819

Merged
szeiger merged 1 commit intoscala:2.12.xfrom
som-snytt:issue/7916-ScriptEngine-deferred
May 20, 2016
Merged

SI-7916: ScriptEngine support#4819
szeiger merged 1 commit intoscala:2.12.xfrom
som-snytt:issue/7916-ScriptEngine-deferred

Conversation

@som-snytt
Copy link
Contributor

Refactor the ScriptEngine support to an adaptor atop the
IMain API.

Allow references to resolve to context attributes. (The
attributes must be defined at compilation time, though
they may resolve to updated values at evaluation time.)

This means that attributes are not bound statically in
REPL history. In particular, we forgo the trick of binding
attributes named "name: Type" as typed values.

Instead, an x bound in dynamic context is injected into
the script as a dynamic selection $ctx.x where ctx
performs the look-up in the script context.

When a compiled script is re-evaluated, a new instance of
the script class is created and defined symbols are
rebound.

@scala-jenkins scala-jenkins added this to the 2.12.0-M4 milestone Oct 26, 2015
@som-snytt som-snytt closed this Oct 26, 2015
@som-snytt
Copy link
Contributor Author

Maybe a useful separation of concerns.

@som-snytt som-snytt reopened this Nov 11, 2015
Copy link
Member

Choose a reason for hiding this comment

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

what is the reason for having this commented line? is this method of getting the script engine tested somewhere else?

@lrytz
Copy link
Member

lrytz commented Dec 18, 2015

This LGTM otherwise, but I'm not really familiar enough with JSR223

@lrytz lrytz self-assigned this Dec 18, 2015
@retronym
Copy link
Member

I think we should get this one in. It needs rebasing, though.

@som-snytt
Copy link
Contributor Author

I'll have to get familiar enough with JSR223.

@som-snytt som-snytt force-pushed the issue/7916-ScriptEngine-deferred branch from 99ee333 to 8876c1d Compare February 2, 2016 06:28
@som-snytt
Copy link
Contributor Author

Added setWriter support to capture Console.out.

@lrytz
Copy link
Member

lrytz commented Feb 16, 2016

The following problem manifests only when using sbt as explained; it works when building locally and running build/pack/bin/scala.

Take this build.sbt file:

resolvers += "Scala PR Validation Snapshots" at "https://scala-ci.typesafe.com/artifactory/scala-pr-validation-snapshots/"

scalaVersion := "2.12.0-8876c1d-SNAPSHOT"

and run sbt console. I get:

Welcome to Scala 2.12.0-8876c1d-SNAPSHOT (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_71).
Type in expressions for evaluation. Or try :help.

scala> import javax.script._; import scala.tools.nsc.interpreter.Scripted
import javax.script._
import scala.tools.nsc.interpreter.Scripted

scala> val m = new ScriptEngineManager()
m: javax.script.ScriptEngineManager = javax.script.ScriptEngineManager@7462718f

scala> m.registerEngineName("scala", new Scripted.Factory)

scala> val s = m.getEngineByName("scala").asInstanceOf[ScriptEngine with Compilable]
s: javax.script.ScriptEngine with javax.script.Compilable = scala.tools.nsc.interpreter.Scripted@7bd80c4b

scala> s.eval("1")
scala.reflect.internal.FatalError: package scala does not have a member Int
  at scala.reflect.internal.Definitions$DefinitionsClass.fatalMissingSymbol(Definitions.scala:1195)
  at scala.reflect.internal.Definitions$DefinitionsClass.scala$reflect$internal$Definitions$DefinitionsClass$$$anonfun$79(Definitions.scala:1218)
  at scala.reflect.internal.Definitions$DefinitionsClass.getMember(Definitions.scala:1213)
  at scala.reflect.internal.Definitions$ValueClassDefinitions$class.valueClassSymbol(Definitions.scala:78)
  at scala.reflect.internal.Definitions$ValueClassDefinitions$class.IntClass(Definitions.scala:119)
  at scala.reflect.internal.Definitions$DefinitionsClass.IntClass$lzycompute(Definitions.scala:158)
  at scala.reflect.internal.Definitions$DefinitionsClass.IntClass(Definitions.scala:158)
  at scala.reflect.internal.Definitions$ValueClassDefinitions$class.IntTpe(Definitions.scala:132)
  at scala.reflect.internal.Definitions$DefinitionsClass.IntTpe$lzycompute(Definitions.scala:158)
  at scala.reflect.internal.Definitions$DefinitionsClass.IntTpe(Definitions.scala:158)
  at scala.tools.nsc.symtab.classfile.ClassfileParser.sig2type$1(ClassfileParser.scala:630)
  at scala.tools.nsc.symtab.classfile.ClassfileParser.sig2type$1(ClassfileParser.scala:728)
  at scala.tools.nsc.symtab.classfile.ClassfileParser.scala$tools$nsc$symtab$classfile$ClassfileParser$$sigToType(ClassfileParser.scala:774)
  at scala.tools.nsc.symtab.classfile.ClassfileParser$ConstantPool.getType(ClassfileParser.scala:289)
  at scala.tools.nsc.symtab.classfile.ClassfileParser.parseMethod(ClassfileParser.scala:568)
  at scala.tools.nsc.symtab.classfile.ClassfileParser.scala$tools$nsc$symtab$classfile$ClassfileParser$$$anonfun$10(ClassfileParser.scala:483)
  at scala.tools.nsc.symtab.classfile.ClassfileParser.queueLoad$1(ClassfileParser.scala:483)
  at scala.tools.nsc.symtab.classfile.ClassfileParser.scala$tools$nsc$symtab$classfile$ClassfileParser$$$anonfun$11(ClassfileParser.scala:493)
  at scala.tools.nsc.symtab.classfile.ClassfileParser.parseClass(ClassfileParser.scala:498)
  at scala.tools.nsc.symtab.classfile.ClassfileParser.scala$tools$nsc$symtab$classfile$ClassfileParser$$$anonfun$2(ClassfileParser.scala:150)
  at scala.tools.nsc.symtab.classfile.ClassfileParser.parse(ClassfileParser.scala:125)
  at scala.tools.nsc.symtab.SymbolLoaders$ClassfileLoader.scala$tools$nsc$symtab$SymbolLoaders$ClassfileLoader$$$anonfun$13(SymbolLoaders.scala:347)
  at scala.tools.nsc.symtab.SymbolLoaders$ClassfileLoader.doComplete(SymbolLoaders.scala:347)
  at scala.tools.nsc.symtab.SymbolLoaders$SymbolLoader.complete(SymbolLoaders.scala:211)
  at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1513)
  at scala.reflect.internal.Symbols$Symbol.initialize(Symbols.scala:1658)
  at scala.reflect.internal.Definitions$DefinitionsClass.init(Definitions.scala:1403)
  at scala.tools.nsc.Global$Run.<init>(Global.scala:1128)
  at scala.tools.nsc.interpreter.IMain._initialize(IMain.scala:120)
  at scala.tools.nsc.interpreter.IMain.global$lzycompute(IMain.scala:149)
  at scala.tools.nsc.interpreter.IMain.global(IMain.scala:148)
  at scala.tools.nsc.interpreter.IMain$naming$.<init>(IMain.scala:177)
  at scala.tools.nsc.interpreter.IMain.naming$lzycompute(IMain.scala:176)
  at scala.tools.nsc.interpreter.IMain.naming(IMain.scala:176)
  at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.<init>(IMain.scala:676)
  at scala.tools.nsc.interpreter.IMain.bind(IMain.scala:607)
  at scala.tools.nsc.interpreter.IMain.bind(IMain.scala:647)
  at scala.tools.nsc.interpreter.IMain.scala$tools$nsc$interpreter$IMain$$$anonfun$59(IMain.scala:646)
  at scala.tools.nsc.interpreter.IMain.beQuietDuring(IMain.scala:202)
  at scala.tools.nsc.interpreter.IMain.quietBind(IMain.scala:646)
  at scala.tools.nsc.interpreter.Scripted.compile(Scripted.scala:95)
  at scala.tools.nsc.interpreter.Scripted.eval(Scripted.scala:129)
  at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)

@lrytz
Copy link
Member

lrytz commented Feb 16, 2016

(the scala library is not on the compilation classpath, i'm trying to figure out why)

@lrytz
Copy link
Member

lrytz commented Feb 16, 2016

I guess it's that usejavacp doesn't work; I set a breakpoint when initializing the compiler classpath and checked System.getProperty("java.class.path"): got /Users/luc/.sbt/launchers/0.13.9/sbt-launch.jar. Ideas how a good classpath / settings could be obtained?

Anyway, this problem seems unrelated to the changes in this PR.

@lrytz
Copy link
Member

lrytz commented Feb 16, 2016

I'm still lacking JSR223 familiarization, but to me this PR looks very good. It could maybe get a little more testing. Here's some log of my playground

Welcome to Scala 2.12.0-20160201-221940-8876c1d715 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_71).
Type in expressions for evaluation. Or try :help.

scala> import javax.script._; import scala.tools.nsc.interpreter.Scripted
import javax.script._
import scala.tools.nsc.interpreter.Scripted

scala> val m = new ScriptEngineManager()
m: javax.script.ScriptEngineManager = javax.script.ScriptEngineManager@5e17553a

scala> m.registerEngineName("scala", new Scripted.Factory)

scala> val s = m.getEngineByName("scala").asInstanceOf[ScriptEngine with Compilable]
s: javax.script.ScriptEngine with javax.script.Compilable = scala.tools.nsc.interpreter.Scripted@726e5805

scala> s.eval("1")
res1: Object = 1

scala>

scala> s.eval("$ctx.foo") // DynamicContext
res2: Object = null

scala> s.eval("$ctx.foo = BigInt(12)")
res3: Object = 12

scala> s.eval("$ctx.foo")
res4: Object = 12

scala> s.eval("foo")
res5: Object = 12

scala>

scala> s.eval("$ctx.bar")
res6: Object = null

scala> s.eval("bar")
<console>:12: error: not found: value bar
       bar
       ^
javax.script.ScriptException: compile-time error
  at scala.tools.nsc.interpreter.Scripted.scala$tools$nsc$interpreter$Scripted$$$anonfun$7(Scripted.scala:111)
  at scala.tools.nsc.interpreter.Scripted$DynamicContext.apply(Scripted.scala:38)
  at scala.tools.nsc.interpreter.Scripted.compile(Scripted.scala:99)
  at scala.tools.nsc.interpreter.Scripted.eval(Scripted.scala:129)
  at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
  ... 30 elided

scala> s.put("bar", 1)

scala> s.eval("$ctx.bar")
res9: Object = 1

scala> s.eval("$ctx.bar = Int.box(23)")
res10: Object = 23

scala> s.eval("$ctx.bar")
res11: Object = 23

scala> s.eval("bar")
res12: Object = 23

scala>

scala> s.eval("baz")
<console>:12: error: not found: value baz
       baz
       ^
javax.script.ScriptException: compile-time error
  at scala.tools.nsc.interpreter.Scripted.scala$tools$nsc$interpreter$Scripted$$$anonfun$7(Scripted.scala:111)
  at scala.tools.nsc.interpreter.Scripted$DynamicContext.apply(Scripted.scala:38)
  at scala.tools.nsc.interpreter.Scripted.compile(Scripted.scala:99)
  at scala.tools.nsc.interpreter.Scripted.eval(Scripted.scala:129)
  at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
  ... 30 elided

scala> s.eval("val baz = -1")
res14: Object = -1

scala> s.eval("baz")
res15: Object = -1

scala> s.eval("$ctx.baz") // still null
res16: Object = null

scala> s.eval("$ctx.baz = Int.box(-2)")
res17: Object = -2

scala> s.eval("baz")
res18: Object = -2

scala> s.eval("$ctx.baz")
res19: Object = -2

scala> s.eval("baz = Int.box(-3)")
res20: Object = -3

@lrytz
Copy link
Member

lrytz commented Feb 16, 2016

@rjolly would you be interested to also review this PR?

//intp quietBind ("engine" -> this.asInstanceOf[ScriptEngine])
//intp quietBind NamedParam[DynamicContext]("$ctx", dynamicContext)
intp quietBind NamedParamClass(intp.ctx, "scala.tools.nsc.interpreter.Scripted#DynamicContext", dynamicContext)
intp quietBind NamedParam[IMain]("$intp", intp)(StdReplTags.tagOfIMain, classTag[IMain])
Copy link
Contributor

Choose a reason for hiding this comment

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

Regarding this line, what I intended was to make the interpreter available as a ScriptEngine, that is, it should be "this" and not "intp" (and the name was "engine", without $, it would be cool if it could remain like this). Otherwise, LGTM.

@som-snytt
Copy link
Contributor Author

This is proof-of-concept; I don't know what the use cases are, for interoperating with Objects; and I haven't exercised it much, for the usual reasons of ignorance and laziness, and not knowing if it's useful to pursue. Suggestions welcome.

@rjolly Am I right that you can usually throw weird names in backticks? The REPL isn't currently as backtick-friendly as it ought to be.

@rjolly
Copy link
Contributor

rjolly commented Feb 17, 2016

@som-snytt I tested it, and it seems my two concerns above are solved on the Java side. For one thing, jrunscript does not bind long names like javax.script.filename and javax.script.argv anymore. Now it binds an "arguments" variable, and also "engine" with the ScriptEngine, which solves my first issue.

@rjolly
Copy link
Contributor

rjolly commented Feb 19, 2016

There is one more caveat, still related to binding variables. With your new scheme, one needs to jarlist not only scala-library.jar, but also scala-compiler.jar and scala-reflect.jar too (as the former depends on it). If not done, one gets (using 2.12.0-8876c1d-SNAPSHOT):

jarlister scala-library.jar
jrunscript -classpath scala-compiler.jar:scala-reflect.jar:scala-library.jar -l scala
scala> "hello world"
<console>:5: error: object tools is not a member of package scala
  var value: scala.tools.nsc.interpreter.Scripted#DynamicContext = _
                   ^
<console>:6: error: object tools is not a member of package scala
  def set(x: Any) = value = x.asInstanceOf[scala.tools.nsc.interpreter.Scripted#DynamicContext]
                                                 ^
<console>:5: error: object tools is not a member of package scala
  var value: scala.tools.nsc.interpreter.IMain = _
                   ^
<console>:6: error: object tools is not a member of package scala
  def set(x: Any) = value = x.asInstanceOf[scala.tools.nsc.interpreter.IMain]
                                                 ^
hello world
scala>

The problem is caused by these lines:

intp quietBind NamedParamClass(intp.ctx, "scala.tools.nsc.interpreter.Scripted#DynamicContext", dynamicContext)
intp quietBind NamedParam[IMain]("$intp", intp)(StdReplTags.tagOfIMain, classTag[IMain])

, which go through the following statement:

bindRep.compile("""
    |object %s {
    |  var value: %s = _
    |  def set(x: Any) = value = x.asInstanceOf[%s]
    |}
  """.stripMargin.format(bindRep.evalName, boundType, boundType)

, causing the errors. Formerly the problem was avoided by casting the interpreter to javax.script.ScriptEngine, which is known outside of scala-compiler.jar . To solve it in the present construct, we could define an interface for DynamicContext , which we would put in scala-library.jar . And again regarding IMain, we should not bind it, but instead "this" (the Scripted instance) as instance of ScriptEngine (or nothing at all, as jrunscript is taking care of it, as seen above).

@MaggieLeber
Copy link

I'm trying to resurrect a year-old branch of our project to see if I can get this to work for us. Our use case is a bit twisty; We have a Play Framework 2.3 application that embeds a Java library that supports JSR-223 script engines...and I need to have the automated tests operate under sbt testOnly of course. I have hacked the Java library (and its classpath) sufficiently to get past the classic package scala does not have a member Int and scala.reflect.internal.FatalError: class StringContext does not have a member f junk.

java.lang.NoSuchMethodError: scala.tools.nsc.interpreter.IMain$.defaultOut()Lscala/tools/nsc/NewLinePrintWriter; is currently happening when I try to print or occasionally even with System.out.println (This may be caused by having 2.12 on the classpath for the Java library while still being on 2.11 for the enclosing Play app...I tried moving the app forward but my Scala dependencies at that level had a conniption,

I'm also kind of stumbling around as to how I reference stuff in the script context. $ctx doesn't appear to be defined, but I may have to dig back into the hacked Java lib and make sure the context is properly set there; I may have broken it trying to get it to work on Scala 2.11, before it was even supported.

Are my comments about my floundering best made here, or back on SI-7916? @lukas Rytz invited me to pop in here and contribute, and kindly provided a 2.12 build with this on it.

@som-snytt
Copy link
Contributor Author

Thanks @rjolly and @MaggieLeber , I'll make time to push it forward. This is the right place to comment on this implementation.

I guess they don't require a SIP or SLIP, or a RIP (repl improvement). I kind of which there were a RIP.

@MaggieLeber
Copy link

I don't have this working yet in my use case. I think I need to do a cut-down exemplar without Play 2.3 and all the myriad dependencies of our app, most of whom don't to yet have 2.12 binaries available.

I'm still unclear how I refer to values in the passed ScriptContext from within the Scala script; $ctx doesn't seem to be working; it gets a compile error, but I'm not absolutely certain I've got the classpath built correctly in my hack on the Java library.

    if (SCALA_SCRIPTING_LANGUAGE.equals(language)) {
        String compilerPath;
        String libPath;
        String thisPath;
        try {
            compilerPath = java.lang.Class.forName("scala.tools.nsc.Interpreter").getProtectionDomain().getCodeSource().getLocation().getPath();
            libPath = java.lang.Class.forName("scala.Some").getProtectionDomain().getCodeSource().getLocation().getPath();
            Class someClass = java.lang.Class.forName("scala.Some");
            ((IMain)scriptEngine).settings().embeddedDefaults(this.getClass().getClassLoader());
        } catch (Exception e) {
            throw new RuntimeException("classpaths boogered", e);
        }
       // ((MutableSettings.BooleanSetting)(((IMain)scriptEngine).settings().usejavacp())).value_$eq(true);
        ((MutableSettings.BooleanSetting)(((IMain)scriptEngine).settings().usemanifestcp())).value_$eq(true);
        ((MutableSettings.PathSetting)(((IMain)scriptEngine).settings().bootclasspath())).append(compilerPath+libPath);
        (((IMain)scriptEngine).settings().classpath()).append(compilerPath+libPath);
    }
}        

My use case looks like this:

image

@MaggieLeber
Copy link

OK, gave up on sorting that mess; it's too complicated. So now I'm trying to run Scala scripts in jMeter as JSR223 samplers.

jMeter finds the ScriptEngine OK, but items placed in the ScriptContext by the host seem to get their type erased all the way back to Object when you try to access their members.

image

<console>:13: error: value info is not a member of Object
       def logit(s : String) = $ctx.log.info

Although if you sneak up on it you can catch it:
image

Error ends up being a handy bottle to put messages in because I have no clue where println is going and I don't seem to be able to get to the Logger or OUT yet.

Update: Progress!
image

Update: it works if you restore the erased type info!!!:

val out = ($ctx.context.getAttribute("OUT")).asInstanceOf[java.io.PrintStream]
out.println("foo for reals")

image

@som-snytt
Copy link
Contributor Author

@MaggieLeber Yes, currently all you get is an Object unless you cast. Example https://github.com/som-snytt/scala/blob/issue/7916-ScriptEngine-deferred/test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala#L21

Previously, it took apart the bound name as a name: Type pair and that's how it was statically "registered" in REPL history. There's no script API to say directly "bind as this type in the target environment."

One could hijack the API with the colon trick, or add a method that includes type info.

@MaggieLeber
Copy link

Unfortunately, I think any approach that erases type information in the objects in a ScriptContext is in for a very rough ride from folks approaching Scala as a JSR223 implemention. It's common for a JSR223 host to chain script executions, sharing their contexts between executions which may occur under different ScriptEngines. Activiti and jMeter are good examples. That said, I suppose it's better than not working at all.

@SethTisue
Copy link
Member

any approach that erases type information in the objects in a ScriptContext is in for a very rough ride from folks approaching Scala as a JSR223 implemention

isn't this an inherent issue with JSR223 itself, rather than a shortcoming of our implementation in particular? (or am I confused?)

@som-snytt
Copy link
Contributor Author

One option is to wrap bound objects in Dynamic. It's dynamic all the way down... I didn't have a chance to look at it yet.

@som-snytt
Copy link
Contributor Author

I wanted to spend a couple of hours on this but hit a snag. Testing with a bad ref, it throws as shown:

https://gist.github.com/som-snytt/361d43d2c78e31364cc6d558e22f0638

I'll push and maybe @lrytz will hint at something.

For @rjolly hint, it pre-compiles a wrapper for the current context and also the dynamic adapter (which isn't strictly required).

@som-snytt som-snytt force-pushed the issue/7916-ScriptEngine-deferred branch from 8876c1d to d232d38 Compare April 18, 2016 04:43
@lrytz
Copy link
Member

lrytz commented Apr 18, 2016

I'll take a look if I can reproduce - ErrorType should not make it to the backend.

@som-snytt
Copy link
Contributor Author

I just noticed that adding the reporter override induces the exception. How is that possible? D'oh, I guess it's because the compiler relies on the reporter correctly reporting error state to halt compilation.

I'm distracted b/c heading to my day job and didn't intend to spend hours on this. But it makes me appreciate what FOSS means as a commitment. Actually I wanted to finish my dotty repl last weekend. :(

@lrytz
Copy link
Member

lrytz commented Apr 18, 2016

compiler relies on the reporter correctly reporting error state to halt compilation

right, it's actually the main loop that moves compiler phases forward: https://github.com/scala/scala/blob/2.12.x/src/compiler/scala/tools/nsc/Global.scala#L1480

it makes me appreciate what FOSS means as a commitment. Actually I wanted to finish my dotty repl last weekend. :(

your commitment is quite unique! feel free to put your efforts where your motivation drags you. but this one will be worth pushing through!

@som-snytt
Copy link
Contributor Author

So a compile error will throw:

javax.script.ScriptException: not found: value fooz in fooz at line number 12 at column number 8

I always doubt if the position is useful...

@som-snytt
Copy link
Contributor Author

I encountered the wontfix where

[quick.repl] /home/apm/projects/snytt/src/repl/scala/tools/nsc/interpreter/Scripted.scala:45: error: not found: value valname_
[quick.repl]                 def `$valname_=`(x: Object) = $ctx.`$valname` = x"""

@lrytz
Copy link
Member

lrytz commented Apr 19, 2016

ah, you mean #4663?

maybe when you're on this one next time, a rebase on current 2.12.x would be useful and unblock CI validation (assuming we manage to unblock CI itself – https://gitter.im/scala/contributors?at=5715ffbd4c2125fc3f03a200)

@som-snytt
Copy link
Contributor Author

This was already rebased, but I haven't looked at squashing yet. In case I wanted to back something out; but probably I'll just move forward. The other desirable was to handle bound objects more dynamically. I think implicit conversion to Dynamic is not supported? That would have made falling back to reflective access easy.

@adriaanm adriaanm assigned szeiger and unassigned SethTisue Apr 26, 2016
@som-snytt som-snytt force-pushed the issue/7916-ScriptEngine-deferred branch from 3f2c039 to c6309fc Compare April 28, 2016 16:31
@som-snytt
Copy link
Contributor Author

Is this that old problem where spiders would poke an abort link?

  [partest] ok 1047 - run/WeakHashSetTest.scala               
Build was aborted
Aborted by anonymous

@som-snytt
Copy link
Contributor Author

/rebuild

@szeiger
Copy link
Contributor

szeiger commented May 19, 2016

If my assessment of this long thread is accurate, everyone's requests have been satisfied and all that remains is resolving the merge conflicts that have crept in. Are there any objections against merging the current state?

@lrytz
Copy link
Member

lrytz commented May 19, 2016

yes, i think so too

@som-snytt
Copy link
Contributor Author

I'll rebase. I think there is a future opportunity for improving the user experience of working with dynamically bound objects, but not a blocker for this PR.

Refactor the ScriptEngine support to an adaptor atop the
IMain API.

Allow references to resolve to context attributes. (The
attributes must be defined at compilation time, though
they may resolve to updated values at evaluation time.)

This means that attributes are not bound statically in
REPL history. In particular, we forgo the trick of binding
attributes named "name: Type" as typed values.

Instead, an `x` bound in dynamic context is injected into
the script as a dynamic selection `$ctx.x` where `ctx`
performs the look-up in the script context.

When a compiled script is re-evaluated, a new instance of
the script class is created and defined symbols are
rebound.

The context stdout writer is handled with `Console.withOut`,
with bytes decoded using the default charset.

Compilation errors are thrown as ScriptException with the
first reported error.

This commit doesn't attempt dynamic selection from objects
in context. Currently, script must cast.
@som-snytt som-snytt force-pushed the issue/7916-ScriptEngine-deferred branch from c6309fc to 3cddeaa Compare May 19, 2016 18:28
@rjolly
Copy link
Contributor

rjolly commented May 19, 2016

No objection.

@szeiger
Copy link
Contributor

szeiger commented May 20, 2016

/rebuild

@szeiger szeiger merged commit 1ea1916 into scala:2.12.x May 20, 2016
@som-snytt som-snytt deleted the issue/7916-ScriptEngine-deferred branch May 31, 2016 17:20
adriaanm added a commit that referenced this pull request Sep 26, 2016
Fix reference to script engine factory in META-INF/services

Follow up for #4819
@adriaanm adriaanm added 2.12 and removed 2.12 labels Oct 29, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants