@Override public Object call(final Object thiz, final Object... args) { final Global oldGlobal = Context.getGlobal(); final boolean globalChanged = (oldGlobal != global); try { if (globalChanged) { Context.setGlobal(global); } if (sobj instanceof ScriptFunction) { final Object[] modArgs = globalChanged ? wrapArray(args, oldGlobal) : args; final Object self = globalChanged ? wrap(thiz, oldGlobal) : thiz; return wrap( ScriptRuntime.apply( (ScriptFunction) sobj, unwrap(self, global), unwrapArray(modArgs, global)), global); } throw new RuntimeException("not a function: " + toString()); } catch (final NashornException ne) { throw ne.initEcmaError(global); } catch (final RuntimeException | Error e) { throw e; } catch (final Throwable t) { throw new RuntimeException(t); } finally { if (globalChanged) { Context.setGlobal(oldGlobal); } } }
/** * Call member function * * @param functionName function name * @param args arguments * @return return value of function */ public Object callMember(final String functionName, final Object... args) { functionName.getClass(); // null check final Global oldGlobal = Context.getGlobal(); final boolean globalChanged = (oldGlobal != global); try { if (globalChanged) { Context.setGlobal(global); } final Object val = sobj.get(functionName); if (val instanceof ScriptFunction) { final Object[] modArgs = globalChanged ? wrapArray(args, oldGlobal) : args; return wrap( ScriptRuntime.apply((ScriptFunction) val, sobj, unwrapArray(modArgs, global)), global); } else if (val instanceof JSObject && ((JSObject) val).isFunction()) { return ((JSObject) val).call(sobj, args); } throw new NoSuchMethodException("No such function " + functionName); } catch (final NashornException ne) { throw ne.initEcmaError(global); } catch (final RuntimeException | Error e) { throw e; } catch (final Throwable t) { throw new RuntimeException(t); } finally { if (globalChanged) { Context.setGlobal(oldGlobal); } } }
// internals only below this. private <V> V inGlobal(final Callable<V> callable) { final Global oldGlobal = Context.getGlobal(); final boolean globalChanged = (oldGlobal != global); if (globalChanged) { Context.setGlobal(global); } try { return callable.call(); } catch (final NashornException ne) { throw ne.initEcmaError(global); } catch (final RuntimeException e) { throw e; } catch (final Exception e) { throw new AssertionError("Cannot happen", e); } finally { if (globalChanged) { Context.setGlobal(oldGlobal); } } }
@Override public Object put(final String key, final Object value) { final ScriptObject oldGlobal = Context.getGlobal(); final boolean globalChanged = (oldGlobal != global); return inGlobal( new Callable<Object>() { @Override public Object call() { final Object modValue = globalChanged ? wrap(value, oldGlobal) : value; return translateUndefined( wrap(sobj.put(key, unwrap(modValue, global), strict), global)); } }); }
@Override public void putAll(final Map<? extends String, ? extends Object> map) { final ScriptObject oldGlobal = Context.getGlobal(); final boolean globalChanged = (oldGlobal != global); inGlobal( new Callable<Object>() { @Override public Object call() { for (final Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) { final Object value = entry.getValue(); final Object modValue = globalChanged ? wrap(value, oldGlobal) : value; sobj.set(entry.getKey(), unwrap(modValue, global), getCallSiteFlags()); } return null; } }); }