public object Run(Context cx) { cx.GetWrapFactory().SetJavaPrimitiveWrap(false); NUnit.Framework.Assert.AreEqual("string[]", cx.EvaluateString(cx.InitStandardObjects(), "new org.mozilla.javascript.tests.Bug496585Test().method('one', 'two', 'three')", "<test>", 1, null)); NUnit.Framework.Assert.AreEqual("string+function", cx.EvaluateString(cx.InitStandardObjects(), "new org.mozilla.javascript.tests.Bug496585Test().method('one', function() {})", "<test>", 1, null)); return null; }
private static object JsConstructor(Context cx, Scriptable scope, Scriptable thisObj, object[] args) { if (args.Length == 0 || args[0] == null || args[0] == Undefined.instance) { object argument = args.Length == 0 ? Undefined.instance : args[0]; throw ScriptRuntime.TypeError1("msg.no.properties", ScriptRuntime.ToString(argument)); } Scriptable obj = ScriptRuntime.ToObject(scope, args[0]); bool keyOnly = args.Length > 1 && ScriptRuntime.ToBoolean(args[1]); if (thisObj != null) { // Called as a function. Convert to iterator if possible. // For objects that implement java.lang.Iterable or // java.util.Iterator, have JavaScript Iterator call the underlying // iteration methods IEnumerator<object> iterator = VMBridge.instance.GetJavaIterator(cx, scope, obj); if (iterator != null) { scope = ScriptableObject.GetTopLevelScope(scope); return cx.GetWrapFactory().Wrap(cx, scope, new NativeIterator.WrappedJavaIterator(iterator, scope), typeof(NativeIterator.WrappedJavaIterator)); } // Otherwise, just call the runtime routine Scriptable jsIterator = ScriptRuntime.ToIterator(cx, scope, obj, keyOnly); if (jsIterator != null) { return jsIterator; } } // Otherwise, just set up to iterate over the properties of the object. // Do not call __iterator__ method. object objectIterator = ScriptRuntime.EnumInit(obj, cx, keyOnly ? ScriptRuntime.ENUMERATE_KEYS_NO_ITERATOR : ScriptRuntime.ENUMERATE_ARRAY_NO_ITERATOR); ScriptRuntime.SetEnumNumbers(objectIterator, true); NativeIterator result = new NativeIterator(objectIterator); result.SetPrototype(ScriptableObject.GetClassPrototype(scope, result.GetClassName())); result.SetParentScope(scope); return result; }
public static Scriptable WrapException(Exception t, Scriptable scope, Context cx) { RhinoException re; string errorName; string errorMsg; Exception javaException = null; if (t is EcmaError) { EcmaError ee = (EcmaError)t; re = ee; errorName = ee.GetName(); errorMsg = ee.GetErrorMessage(); } else { if (t is WrappedException) { WrappedException we = (WrappedException)t; re = we; javaException = we.GetWrappedException(); errorName = "JavaException"; errorMsg = javaException.GetType().FullName + ": " + javaException.Message; } else { if (t is EvaluatorException) { // Pure evaluator exception, nor WrappedException instance EvaluatorException ee = (EvaluatorException)t; re = ee; errorName = "InternalError"; errorMsg = ee.Message; } else { if (cx.HasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS)) { // With FEATURE_ENHANCED_JAVA_ACCESS, scripts can catch // all exception types re = new WrappedException(t); errorName = "JavaException"; errorMsg = t.ToString(); } else { // Script can catch only instances of JavaScriptException, // EcmaError and EvaluatorException throw Kit.CodeBug(); } } } } string sourceUri = re.SourceName(); if (sourceUri == null) { sourceUri = string.Empty; } int line = re.LineNumber(); object[] args; if (line > 0) { args = new object[] { errorMsg, sourceUri, Sharpen.Extensions.ValueOf(line) }; } else { args = new object[] { errorMsg, sourceUri }; } Scriptable errorObject = cx.NewObject(scope, errorName, args); ScriptableObject.PutProperty(errorObject, "name", errorName); // set exception in Error objects to enable non-ECMA "stack" property if (errorObject is NativeError) { ((NativeError)errorObject).SetStackProvider(re); } if (javaException != null && IsVisible(cx, javaException)) { object wrap = cx.GetWrapFactory().Wrap(cx, scope, javaException, null); ScriptableObject.DefineProperty(errorObject, "javaException", wrap, ScriptableObject.PERMANENT | ScriptableObject.READONLY); } if (IsVisible(cx, re)) { object wrap = cx.GetWrapFactory().Wrap(cx, scope, re, null); ScriptableObject.DefineProperty(errorObject, "rhinoException", wrap, ScriptableObject.PERMANENT | ScriptableObject.READONLY); } return errorObject; }
/// <summary>Convert the value to an object.</summary> /// <remarks> /// Convert the value to an object. /// See ECMA 9.9. /// </remarks> public static Scriptable ToObject(Context cx, Scriptable scope, object val) { if (val is Scriptable) { return (Scriptable)val; } if (val is CharSequence) { // FIXME we want to avoid toString() here, especially for concat() NativeString result = new NativeString((CharSequence)val); SetBuiltinProtoAndParent(result, scope, TopLevel.Builtins.String); return result; } if (val is Number) { NativeNumber result = new NativeNumber(System.Convert.ToDouble(((Number)val))); SetBuiltinProtoAndParent(result, scope, TopLevel.Builtins.Number); return result; } if (val is bool) { NativeBoolean result = new NativeBoolean(((bool)val)); SetBuiltinProtoAndParent(result, scope, TopLevel.Builtins.Boolean); return result; } if (val == null) { throw TypeError0("msg.null.to.object"); } if (val == Undefined.instance) { throw TypeError0("msg.undef.to.object"); } // Extension: Wrap as a LiveConnect object. object wrapped = cx.GetWrapFactory().Wrap(cx, scope, val, null); if (wrapped is Scriptable) { return (Scriptable)wrapped; } throw ErrorWithClassName("msg.invalid.type", val); }
internal virtual object InvokeImpl(Context cx, object target, Scriptable topScope, object thisObject, MethodInfo method, object[] args) { Callable function; if (target is Callable) { function = (Callable)target; } else { Scriptable s = (Scriptable)target; string methodName = method.Name; object value = ScriptableObject.GetProperty(s, methodName); if (value == ScriptableObject.NOT_FOUND) { // We really should throw an error here, but for the sake of // compatibility with JavaAdapter we silently ignore undefined // methods. Context.ReportWarning(ScriptRuntime.GetMessage1("msg.undefined.function.interface", methodName)); Type resultType = method.ReturnType; if (resultType == typeof(void)) { return null; } else { return Context.JsToJava(null, resultType); } } if (!(value is Callable)) { throw Context.ReportRuntimeError1("msg.not.function.interface", methodName); } function = (Callable)value; } WrapFactory wf = cx.GetWrapFactory(); if (args == null) { args = ScriptRuntime.emptyArgs; } else { for (int i = 0, N = args.Length; i != N; ++i) { object arg = args[i]; // neutralize wrap factory java primitive wrap feature if (!(arg is string || arg is Number || arg is bool)) { args[i] = wf.Wrap(cx, topScope, arg, null); } } } Scriptable thisObj = wf.WrapAsJavaObject(cx, topScope, thisObject, null); object result = function.Call(cx, topScope, thisObj, args); Type javaResultType = method.ReturnType; if (javaResultType == typeof(void)) { result = null; } else { result = Context.JsToJava(result, javaResultType); } return result; }
public override object Call(Context cx, Scriptable scope, Scriptable thisObj, object[] args) { // Find a method that matches the types given. if (methods.Length == 0) { throw new Exception("No methods defined for call"); } int index = FindCachedFunction(cx, args); if (index < 0) { Type c = methods[0].Method().DeclaringType; string sig = c.FullName + '.' + GetFunctionName() + '(' + ScriptSignature(args) + ')'; throw Context.ReportRuntimeError1("msg.java.no_such_method", sig); } MemberBox meth = methods[index]; Type[] argTypes = meth.argTypes; if (meth.vararg) { // marshall the explicit parameters object[] newArgs = new object[argTypes.Length]; for (int i = 0; i < argTypes.Length - 1; i++) { newArgs[i] = Context.JsToJava(args[i], argTypes[i]); } object varArgs; // Handle special situation where a single variable parameter // is given and it is a Java or ECMA array or is null. if (args.Length == argTypes.Length && (args[args.Length - 1] == null || args[args.Length - 1] is NativeArray || args[args.Length - 1] is NativeJavaArray)) { // convert the ECMA array into a native array varArgs = Context.JsToJava(args[args.Length - 1], argTypes[argTypes.Length - 1]); } else { // marshall the variable parameters Type componentType = argTypes[argTypes.Length - 1].GetElementType(); varArgs = System.Array.CreateInstance(componentType, args.Length - argTypes.Length + 1); for (int i_1 = 0; i_1 < Sharpen.Runtime.GetArrayLength(varArgs); i_1++) { object value = Context.JsToJava(args[argTypes.Length - 1 + i_1], componentType); Sharpen.Runtime.SetArrayValue(varArgs, i_1, value); } } // add varargs newArgs[argTypes.Length - 1] = varArgs; // replace the original args with the new one args = newArgs; } else { // First, we marshall the args. object[] origArgs = args; for (int i = 0; i < args.Length; i++) { object arg = args[i]; object coerced = Context.JsToJava(arg, argTypes[i]); if (coerced != arg) { if (origArgs == args) { args = args.Clone(); } args[i] = coerced; } } } object javaObject; if (meth.IsStatic()) { javaObject = null; } else { // don't need an object Scriptable o = thisObj; Type c = meth.GetDeclaringClass(); for (; ; ) { if (o == null) { throw Context.ReportRuntimeError3("msg.nonjava.method", GetFunctionName(), ScriptRuntime.ToString(thisObj), c.FullName); } if (o is Wrapper) { javaObject = ((Wrapper)o).Unwrap(); if (c.IsInstanceOfType(javaObject)) { break; } } o = o.GetPrototype(); } } object retval = meth.Invoke(javaObject, args); Type staticType = meth.Method().ReturnType; object wrapped = cx.GetWrapFactory().Wrap(cx, scope, retval, staticType); if (wrapped == null && staticType == typeof(void)) { wrapped = Undefined.instance; } return wrapped; }
internal static Scriptable ConstructSpecific(Context cx, Scriptable scope, object[] args, MemberBox ctor) { object instance = ConstructInternal(args, ctor); // we need to force this to be wrapped, because construct _has_ // to return a scriptable Scriptable topLevel = ScriptableObject.GetTopLevelScope(scope); return cx.GetWrapFactory().WrapNewObject(cx, topLevel, instance); }
public virtual Scriptable Construct(Context cx, Scriptable scope, object[] args) { Type classObject = GetClassObject(); int modifiers = classObject.Attributes; if (!(Modifier.IsInterface(modifiers) || Modifier.IsAbstract(modifiers))) { NativeJavaMethod ctors = members.ctors; int index = ctors.FindCachedFunction(cx, args); if (index < 0) { string sig = NativeJavaMethod.ScriptSignature(args); throw Context.ReportRuntimeError2("msg.no.java.ctor", classObject.FullName, sig); } // Found the constructor, so try invoking it. return ConstructSpecific(cx, scope, args, ctors.methods[index]); } else { if (args.Length == 0) { throw Context.ReportRuntimeError0("msg.adapter.zero.args"); } Scriptable topLevel = ScriptableObject.GetTopLevelScope(this); string msg = string.Empty; try { // When running on Android create an InterfaceAdapter since our // bytecode generation won't work on Dalvik VM. if ("Dalvik".Equals(Runtime.GetProperty("java.vm.name")) && classObject.IsInterface) { object obj = CreateInterfaceAdapter(classObject, ScriptableObject.EnsureScriptableObject(args[0])); return cx.GetWrapFactory().WrapAsJavaObject(cx, scope, obj, null); } // use JavaAdapter to construct a new class on the fly that // implements/extends this interface/abstract class. object v = topLevel.Get("JavaAdapter", topLevel); if (v != ScriptableConstants.NOT_FOUND) { Function f = (Function)v; // Args are (interface, js object) object[] adapterArgs = new object[] { this, args[0] }; return f.Construct(cx, topLevel, adapterArgs); } } catch (Exception ex) { // fall through to error string m = ex.Message; if (m != null) { msg = m; } } throw Context.ReportRuntimeError2("msg.cant.instantiate", msg, classObject.FullName); } }
/// <summary> /// Performs conversions on argument types if needed and /// invokes the underlying Java method or constructor. /// </summary> /// <remarks> /// Performs conversions on argument types if needed and /// invokes the underlying Java method or constructor. /// <p> /// Implements Function.call. /// </remarks> /// <seealso cref="Function.Call(Context, Scriptable, Scriptable, object[])">Function.Call(Context, Scriptable, Scriptable, object[])</seealso> public override object Call(Context cx, Scriptable scope, Scriptable thisObj, object[] args) { object result; bool checkMethodResult = false; int argsLength = args.Length; for (int i = 0; i < argsLength; i++) { // flatten cons-strings before passing them as arguments if (args[i] is ConsString) { args[i] = args[i].ToString(); } } if (parmsLength < 0) { if (parmsLength == VARARGS_METHOD) { object[] invokeArgs = new object[] { cx, thisObj, args, this }; result = member.Invoke(null, invokeArgs); checkMethodResult = true; } else { bool inNewExpr = (thisObj == null); bool b = inNewExpr ? true : false; object[] invokeArgs = new object[] { cx, args, this, b }; result = (member.IsCtor()) ? member.NewInstance(invokeArgs) : member.Invoke(null, invokeArgs); } } else { if (!isStatic) { Type clazz = member.GetDeclaringClass(); if (!clazz.IsInstanceOfType(thisObj)) { bool compatible = false; if (thisObj == scope) { Scriptable parentScope = GetParentScope(); if (scope != parentScope) { // Call with dynamic scope for standalone function, // use parentScope as thisObj compatible = clazz.IsInstanceOfType(parentScope); if (compatible) { thisObj = parentScope; } } } if (!compatible) { // Couldn't find an object to call this on. throw ScriptRuntime.TypeError1("msg.incompat.call", functionName); } } } object[] invokeArgs; if (parmsLength == argsLength) { // Do not allocate new argument array if java arguments are // the same as the original js ones. invokeArgs = args; for (int i_1 = 0; i_1 != parmsLength; ++i_1) { object arg = args[i_1]; object converted = ConvertArg(cx, scope, arg, typeTags[i_1]); if (arg != converted) { if (invokeArgs == args) { invokeArgs = args.Clone(); } invokeArgs[i_1] = converted; } } } else { if (parmsLength == 0) { invokeArgs = ScriptRuntime.emptyArgs; } else { invokeArgs = new object[parmsLength]; for (int i_1 = 0; i_1 != parmsLength; ++i_1) { object arg = (i_1 < argsLength) ? args[i_1] : Undefined.instance; invokeArgs[i_1] = ConvertArg(cx, scope, arg, typeTags[i_1]); } } } if (member.IsMethod()) { result = member.Invoke(thisObj, invokeArgs); checkMethodResult = true; } else { result = member.NewInstance(invokeArgs); } } if (checkMethodResult) { if (hasVoidReturn) { result = Undefined.instance; } else { if (returnTypeTag == JAVA_UNSUPPORTED_TYPE) { result = cx.GetWrapFactory().Wrap(cx, scope, result, null); } } } // XXX: the code assumes that if returnTypeTag == JAVA_OBJECT_TYPE // then the Java method did a proper job of converting the // result to JS primitive or Scriptable to avoid // potentially costly Context.javaToJS call. return result; }