/** * ECMA 15.4.4.2 Array.prototype.toString ( ) * * @param self self reference * @return string representation of array */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static Object toString(final Object self) { final Object obj = Global.toObject(self); if (obj instanceof ScriptObject) { final InvokeByName joinInvoker = getJOIN(); final ScriptObject sobj = (ScriptObject)obj; try { final Object join = joinInvoker.getGetter().invokeExact(sobj); if (Bootstrap.isCallable(join)) { return joinInvoker.getInvoker().invokeExact(join, sobj); } } catch (final RuntimeException | Error e) { throw e; } catch (final Throwable t) { throw new RuntimeException(t); } } // FIXME: should lookup Object.prototype.toString and call that? return ScriptRuntime.builtinObjectToString(self); }
/** * ECMA 15.2.4.3 Object.prototype.toLocaleString ( ) * * @param self self reference * @return localized ToString */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static Object toLocaleString(final Object self) { final Object obj = JSType.toScriptObject(self); if (obj instanceof ScriptObject) { final InvokeByName toStringInvoker = getTO_STRING(); final ScriptObject sobj = (ScriptObject)self; try { final Object toString = toStringInvoker.getGetter().invokeExact(sobj); if (Bootstrap.isCallable(toString)) { return toStringInvoker.getInvoker().invokeExact(toString, sobj); } } catch (final RuntimeException | Error e) { throw e; } catch (final Throwable t) { throw new RuntimeException(t); } throw typeError("not.a.function", "toString"); } return ScriptRuntime.builtinObjectToString(self); }
@Override public final void add(final int index, final Object e) { try { if(index < 0) { throw invalidIndex(index); } else if(index == 0) { addFirst(e); } else { final int size = size(); if(index < size) { final InvokeByName spliceAddInvoker = getSPLICE_ADD(); final Object fn = spliceAddInvoker.getGetter().invokeExact(obj); checkFunction(fn, spliceAddInvoker); spliceAddInvoker.getInvoker().invokeExact(fn, obj, index, 0, e); } else if(index == size) { addLast(e); } else { throw invalidIndex(index); } } } catch(final RuntimeException | Error ex) { throw ex; } catch(final Throwable t) { throw new RuntimeException(t); } }
/** * Initialize standard builtin objects like "Object", "Array", "Function" etc. * as well as our extension builtin objects like "Java", "JSAdapter" as properties * of the global scope object. * * @param eng ScriptEngine to initialize */ public void initBuiltinObjects(final ScriptEngine eng) { if (this.builtinObject != null) { // already initialized, just return return; } TO_STRING = new InvokeByName("toString", ScriptObject.class); VALUE_OF = new InvokeByName("valueOf", ScriptObject.class); this.engine = eng; if (this.engine != null) { this.scontext = new ThreadLocal<>(); } init(eng); }
/** * ECMA 15.2.4.3 Object.prototype.toLocaleString ( ) * * @param self self reference * @return localized ToString */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static Object toLocaleString(final Object self) { final Object obj = JSType.toScriptObject(self); if (obj instanceof ScriptObject) { final InvokeByName toStringInvoker = getTO_STRING(); final ScriptObject sobj = (ScriptObject)obj; try { final Object toString = toStringInvoker.getGetter().invokeExact(sobj); if (Bootstrap.isCallable(toString)) { return toStringInvoker.getInvoker().invokeExact(toString, sobj); } } catch (final RuntimeException | Error e) { throw e; } catch (final Throwable t) { throw new RuntimeException(t); } throw typeError("not.a.function", "toString"); } return ScriptRuntime.builtinObjectToString(self); }
@Override public final void add(int index, Object e) { try { if(index < 0) { throw invalidIndex(index); } else if(index == 0) { addFirst(e); } else { final int size = size(); if(index < size) { final InvokeByName spliceAddInvoker = getSPLICE_ADD(); final Object fn = spliceAddInvoker.getGetter().invokeExact(obj); checkFunction(fn, spliceAddInvoker); spliceAddInvoker.getInvoker().invokeExact(fn, obj, index, 0, e); } else if(index == size) { addLast(e); } else { throw invalidIndex(index); } } } catch(RuntimeException | Error ex) { throw ex; } catch(Throwable t) { throw new RuntimeException(t); } }
private static InvokeByName getTO_JSON() { return Global.instance().getInvokeByName(TO_JSON, new Callable<InvokeByName>() { @Override public InvokeByName call() { return new InvokeByName("toJSON", ScriptObject.class, Object.class, Object.class); } }); }
private static InvokeByName getJOIN() { return Global.instance().getInvokeByName(JOIN, new Callable<InvokeByName>() { @Override public InvokeByName call() { return new InvokeByName("join", ScriptObject.class); } }); }
private static InvokeByName getTO_LOCALE_STRING() { return Global.instance().getInvokeByName(TO_LOCALE_STRING, new Callable<InvokeByName>() { @Override public InvokeByName call() { return new InvokeByName("toLocaleString", ScriptObject.class, String.class); } }); }
private static InvokeByName getTO_ISO_STRING() { return Global.instance().getInvokeByName(TO_ISO_STRING, new Callable<InvokeByName>() { @Override public InvokeByName call() { return new InvokeByName("toISOString", ScriptObject.class, Object.class, Object.class); } }); }
/** * ECMA 15.9.5.44 Date.prototype.toJSON ( key ) * * Provides a string representation of this Date for use by {@link NativeJSON#stringify(Object, Object, Object, Object)} * * @param self self reference * @param key ignored * @return JSON representation of this date */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static Object toJSON(final Object self, final Object key) { // NOTE: Date.prototype.toJSON is generic. Accepts other objects as well. final Object selfObj = Global.toObject(self); if (!(selfObj instanceof ScriptObject)) { return null; } final ScriptObject sobj = (ScriptObject)selfObj; final Object value = sobj.getDefaultValue(Number.class); if (value instanceof Number) { final double num = ((Number)value).doubleValue(); if (isInfinite(num) || isNaN(num)) { return null; } } try { final InvokeByName toIsoString = getTO_ISO_STRING(); final Object func = toIsoString.getGetter().invokeExact(sobj); if (Bootstrap.isCallable(func)) { return toIsoString.getInvoker().invokeExact(func, sobj, key); } throw typeError("not.a.function", ScriptRuntime.safeToString(func)); } catch (final RuntimeException | Error e) { throw e; } catch (final Throwable t) { throw new RuntimeException(t); } }
private static InvokeByName getTO_STRING() { return Global.instance().getInvokeByName(TO_STRING, new Callable<InvokeByName>() { @Override public InvokeByName call() { return new InvokeByName("toString", ScriptObject.class); } }); }
private static InvokeByName getPUSH() { return Context.getGlobal().getInvokeByName(PUSH, new Callable<InvokeByName>() { @Override public InvokeByName call() { return new InvokeByName("push", Object.class, void.class, Object.class); } }); }
private static InvokeByName getUNSHIFT() { return Context.getGlobal().getInvokeByName(UNSHIFT, new Callable<InvokeByName>() { @Override public InvokeByName call() { return new InvokeByName("unshift", Object.class, void.class, Object.class); } }); }
private static InvokeByName getPOP() { return Context.getGlobal().getInvokeByName(POP, new Callable<InvokeByName>() { @Override public InvokeByName call() { return new InvokeByName("pop", Object.class, Object.class); } }); }
private static InvokeByName getSHIFT() { return Context.getGlobal().getInvokeByName(SHIFT, new Callable<InvokeByName>() { @Override public InvokeByName call() { return new InvokeByName("shift", Object.class, Object.class); } }); }
private static InvokeByName getSPLICE_ADD() { return Context.getGlobal().getInvokeByName(SPLICE_ADD, new Callable<InvokeByName>() { @Override public InvokeByName call() { return new InvokeByName("splice", Object.class, void.class, int.class, int.class, Object.class); } }); }
private static InvokeByName getSPLICE_REMOVE() { return Context.getGlobal().getInvokeByName(SPLICE_REMOVE, new Callable<InvokeByName>() { @Override public InvokeByName call() { return new InvokeByName("splice", Object.class, void.class, int.class, int.class); } }); }
@Override public final void addFirst(final Object e) { try { final InvokeByName unshiftInvoker = getUNSHIFT(); final Object fn = unshiftInvoker.getGetter().invokeExact(obj); checkFunction(fn, unshiftInvoker); unshiftInvoker.getInvoker().invokeExact(fn, obj, e); } catch(RuntimeException | Error ex) { throw ex; } catch(final Throwable t) { throw new RuntimeException(t); } }