internal static extern JsErrorCode JsCreateFunction(JsNativeFunction nativeFunction, IntPtr externalData,
			out JsValue function);
		internal static extern JsErrorCode JsCreateNamedFunction(JsValue name, JsNativeFunction nativeFunction,
			IntPtr callbackState, out JsValue function);
Ejemplo n.º 3
0
        private EmbeddedType CreateEmbeddedType(Type type)
        {
#if NET40
            Type typeInfo = type;
#else
            TypeInfo typeInfo = type.GetTypeInfo();
#endif
            string            typeName            = type.FullName;
            BindingFlags      defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(true);
            ConstructorInfo[] constructors        = type.GetConstructors(defaultBindingFlags);

            JsNativeFunction nativeConstructorFunction = (callee, isConstructCall, args, argCount, callbackData) =>
            {
                object   result;
                JsValue  resultValue;
                object[] processedArgs = GetHostItemMemberArguments(args);

                if (processedArgs.Length == 0 && typeInfo.IsValueType)
                {
                    result      = Activator.CreateInstance(type);
                    resultValue = MapToScriptType(result);

                    return(resultValue);
                }

                if (constructors.Length == 0)
                {
                    JsValue undefinedValue = JsValue.Undefined;
                    JsValue errorValue     = JsErrorHelpers.CreateError(
                        string.Format(Strings.Runtime_HostTypeConstructorNotFound, typeName));
                    JsErrorHelpers.SetException(errorValue);

                    return(undefinedValue);
                }

                var bestFitConstructor = (ConstructorInfo)ReflectionHelpers.GetBestFitMethod(
                    constructors, processedArgs);
                if (bestFitConstructor == null)
                {
                    JsValue undefinedValue = JsValue.Undefined;
                    JsValue errorValue     = JsErrorHelpers.CreateReferenceError(
                        string.Format(Strings.Runtime_SuitableConstructorOfHostTypeNotFound, typeName));
                    JsErrorHelpers.SetException(errorValue);

                    return(undefinedValue);
                }

                ReflectionHelpers.FixArgumentTypes(ref processedArgs, bestFitConstructor.GetParameters());

                try
                {
                    result = bestFitConstructor.Invoke(processedArgs);
                }
                catch (Exception e)
                {
                    JsValue undefinedValue = JsValue.Undefined;
                    JsValue errorValue     = JsErrorHelpers.CreateError(
                        string.Format(Strings.Runtime_HostTypeConstructorInvocationFailed, typeName, e.Message));
                    JsErrorHelpers.SetException(errorValue);

                    return(undefinedValue);
                }

                resultValue = MapToScriptType(result);

                return(resultValue);
            };

            GCHandle embeddedTypeHandle = GCHandle.Alloc(type);
            IntPtr   embeddedTypePtr    = GCHandle.ToIntPtr(embeddedTypeHandle);
            JsValue  objValue           = JsValue.CreateExternalObject(embeddedTypePtr, _embeddedTypeFinalizeCallback);

            JsValue typeValue = JsValue.CreateFunction(nativeConstructorFunction);
            SetNonEnumerableProperty(typeValue, ExternalObjectPropertyName, objValue);

            var embeddedType = new EmbeddedType(type, typeValue,
                                                new List <JsNativeFunction> {
                nativeConstructorFunction
            });

            ProjectFields(embeddedType);
            ProjectProperties(embeddedType);
            ProjectMethods(embeddedType);
            FreezeObject(typeValue);

            return(embeddedType);
        }
Ejemplo n.º 4
0
        private void ProjectProperties(EmbeddedItem externalItem)
        {
            Type    type      = externalItem.HostType;
            object  obj       = externalItem.HostObject;
            JsValue typeValue = externalItem.ScriptValue;
            IList <JsNativeFunction> nativeFunctions = externalItem.NativeFunctions;
            bool instance = externalItem.IsInstance;

            string       typeName            = type.FullName;
            BindingFlags defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(instance);

            PropertyInfo[] properties = type.GetProperties(defaultBindingFlags);

            foreach (PropertyInfo property in properties)
            {
                string propertyName = property.Name;

                JsValue descriptorValue = JsValue.CreateObject();
                descriptorValue.SetProperty("enumerable", JsValue.True, true);

                if (property.GetGetMethod() != null)
                {
                    JsNativeFunction nativeGetFunction = (callee, isConstructCall, args, argCount, callbackData) =>
                    {
                        if (instance && obj == null)
                        {
                            JsValue undefinedValue = JsValue.Undefined;
                            JsValue errorValue     = JsErrorHelpers.CreateTypeError(
                                string.Format(Strings.Runtime_InvalidThisContextForHostObjectProperty, propertyName));
                            JsErrorHelpers.SetException(errorValue);

                            return(undefinedValue);
                        }

                        object result;

                        try
                        {
                            result = property.GetValue(obj, new object[0]);
                        }
                        catch (Exception e)
                        {
                            string errorMessage = instance ?
                                                  string.Format(
                                Strings.Runtime_HostObjectPropertyGettingFailed, propertyName, e.Message)
                                                                :
                                                  string.Format(
                                Strings.Runtime_HostTypePropertyGettingFailed, propertyName, typeName, e.Message)
                            ;

                            JsValue undefinedValue = JsValue.Undefined;
                            JsValue errorValue     = JsErrorHelpers.CreateError(errorMessage);
                            JsErrorHelpers.SetException(errorValue);

                            return(undefinedValue);
                        }

                        JsValue resultValue = MapToScriptType(result);

                        return(resultValue);
                    };
                    nativeFunctions.Add(nativeGetFunction);

                    JsValue getMethodValue = JsValue.CreateFunction(nativeGetFunction);
                    descriptorValue.SetProperty("get", getMethodValue, true);
                }

                if (property.GetSetMethod() != null)
                {
                    JsNativeFunction nativeSetFunction = (callee, isConstructCall, args, argCount, callbackData) =>
                    {
                        if (instance && obj == null)
                        {
                            JsValue undefinedValue = JsValue.Undefined;
                            JsValue errorValue     = JsErrorHelpers.CreateTypeError(
                                string.Format(Strings.Runtime_InvalidThisContextForHostObjectProperty, propertyName));
                            JsErrorHelpers.SetException(errorValue);

                            return(undefinedValue);
                        }

                        object value = MapToHostType(args[1]);
                        ReflectionHelpers.FixPropertyValueType(ref value, property);

                        try
                        {
                            property.SetValue(obj, value, new object[0]);
                        }
                        catch (Exception e)
                        {
                            string errorMessage = instance ?
                                                  string.Format(
                                Strings.Runtime_HostObjectPropertySettingFailed, propertyName, e.Message)
                                                                :
                                                  string.Format(
                                Strings.Runtime_HostTypePropertySettingFailed, propertyName, typeName, e.Message)
                            ;

                            JsValue undefinedValue = JsValue.Undefined;
                            JsValue errorValue     = JsErrorHelpers.CreateError(errorMessage);
                            JsErrorHelpers.SetException(errorValue);

                            return(undefinedValue);
                        }

                        return(JsValue.Undefined);
                    };
                    nativeFunctions.Add(nativeSetFunction);

                    JsValue setMethodValue = JsValue.CreateFunction(nativeSetFunction);
                    descriptorValue.SetProperty("set", setMethodValue, true);
                }

                typeValue.DefineProperty(propertyName, descriptorValue);
            }
        }
Ejemplo n.º 5
0
 internal static extern JsErrorCode JsCreateFunction(JsNativeFunction nativeFunction, IntPtr externalData,
                                                     out JsValue function);
Ejemplo n.º 6
0
 internal static extern JsErrorCode JsCreateNamedFunction(JsValue name, JsNativeFunction nativeFunction,
                                                          IntPtr callbackState, out JsValue function);
Ejemplo n.º 7
0
		/// <summary>
		/// Creates a new JavaScript function
		/// </summary>
		/// <remarks>
		/// Requires an active script context.
		/// </remarks>
		/// <param name="function">The method to call when the function is invoked</param>
		/// <param name="callbackData">Data to be provided to all function callbacks</param>
		/// <returns>The new function object</returns>
		public static JsValue CreateFunction(JsNativeFunction function, IntPtr callbackData)
		{
			JsValue reference;
			JsErrorHelpers.ThrowIfError(NativeMethods.JsCreateFunction(function, callbackData, out reference));

			return reference;
		}
Ejemplo n.º 8
0
 public static extern JsErrorCode JsCreateNamedFunction(JsValueRef name, JsNativeFunction nativeFunction, IntPtr callbackState, out JsValueRef function);
Ejemplo n.º 9
0
        private void ProjectFields(EmbeddedItem externalItem)
        {
            Type    type      = externalItem.HostType;
            object  obj       = externalItem.HostObject;
            JsValue typeValue = externalItem.ScriptValue;
            bool    instance  = externalItem.IsInstance;
            IList <JsNativeFunction> nativeFunctions = externalItem.NativeFunctions;

            string       typeName            = type.FullName;
            BindingFlags defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(instance);

            FieldInfo[] fields = type.GetFields(defaultBindingFlags);

            foreach (FieldInfo field in fields)
            {
                string fieldName = field.Name;

                JsValue descriptorValue = JsValue.CreateObject();
                descriptorValue.SetProperty("enumerable", JsValue.True, true);

                JsNativeFunction nativeGetFunction = (callee, isConstructCall, args, argCount, callbackData) =>
                {
                    if (instance && obj == null)
                    {
                        CreateAndSetTypeError(string.Format(
                                                  Strings.Runtime_InvalidThisContextForHostObjectField, fieldName));
                        return(JsValue.Undefined);
                    }

                    object result;

                    try
                    {
                        result = field.GetValue(obj);
                    }
                    catch (Exception e)
                    {
                        Exception exception        = UnwrapException(e);
                        var       wrapperException = exception as WrapperException;
                        JsValue   errorValue;

                        if (wrapperException != null)
                        {
                            errorValue = CreateErrorFromWrapperException(wrapperException);
                        }
                        else
                        {
                            string errorMessage = instance ?
                                                  string.Format(Strings.Runtime_HostObjectFieldGettingFailed, fieldName,
                                                                exception.Message)
                                                                :
                                                  string.Format(Strings.Runtime_HostTypeFieldGettingFailed, fieldName, typeName,
                                                                exception.Message)
                            ;
                            errorValue = JsErrorHelpers.CreateError(errorMessage);
                        }
                        JsContext.SetException(errorValue);

                        return(JsValue.Undefined);
                    }

                    JsValue resultValue = MapToScriptType(result);

                    return(resultValue);
                };
                nativeFunctions.Add(nativeGetFunction);

                JsValue getMethodValue = JsValue.CreateFunction(nativeGetFunction);
                descriptorValue.SetProperty("get", getMethodValue, true);

                JsNativeFunction nativeSetFunction = (callee, isConstructCall, args, argCount, callbackData) =>
                {
                    if (instance && obj == null)
                    {
                        CreateAndSetTypeError(string.Format(
                                                  Strings.Runtime_InvalidThisContextForHostObjectField, fieldName));
                        return(JsValue.Undefined);
                    }

                    object value = MapToHostType(args[1]);
                    ReflectionHelpers.FixFieldValueType(ref value, field);

                    try
                    {
                        field.SetValue(obj, value);
                    }
                    catch (Exception e)
                    {
                        Exception exception        = UnwrapException(e);
                        var       wrapperException = exception as WrapperException;
                        JsValue   errorValue;

                        if (wrapperException != null)
                        {
                            errorValue = CreateErrorFromWrapperException(wrapperException);
                        }
                        else
                        {
                            string errorMessage = instance ?
                                                  string.Format(Strings.Runtime_HostObjectFieldSettingFailed, fieldName,
                                                                exception.Message)
                                                                :
                                                  string.Format(Strings.Runtime_HostTypeFieldSettingFailed, fieldName, typeName,
                                                                exception.Message)
                            ;
                            errorValue = JsErrorHelpers.CreateError(errorMessage);
                        }
                        JsContext.SetException(errorValue);

                        return(JsValue.Undefined);
                    }

                    return(JsValue.Undefined);
                };
                nativeFunctions.Add(nativeSetFunction);

                JsValue setMethodValue = JsValue.CreateFunction(nativeSetFunction);
                descriptorValue.SetProperty("set", setMethodValue, true);

                typeValue.DefineProperty(fieldName, descriptorValue);
            }
        }
Ejemplo n.º 10
0
        private void ProjectMethods(EmbeddedItem externalItem)
        {
            Type    type      = externalItem.HostType;
            object  obj       = externalItem.HostObject;
            JsValue typeValue = externalItem.ScriptValue;
            IList <JsNativeFunction> nativeFunctions = externalItem.NativeFunctions;
            bool instance = externalItem.IsInstance;

            string                   typeName            = type.FullName;
            BindingFlags             defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(instance);
            IEnumerable <MethodInfo> methods             = type.GetMethods(defaultBindingFlags)
                                                           .Where(ReflectionHelpers.IsFullyFledgedMethod);
            IEnumerable <IGrouping <string, MethodInfo> > methodGroups = methods.GroupBy(m => m.Name);

            foreach (IGrouping <string, MethodInfo> methodGroup in methodGroups)
            {
                string       methodName       = methodGroup.Key;
                MethodInfo[] methodCandidates = methodGroup.ToArray();

                JsNativeFunction nativeFunction = (callee, isConstructCall, args, argCount, callbackData) =>
                {
                    if (instance && obj == null)
                    {
                        CreateAndSetTypeError(string.Format(
                                                  Strings.Runtime_InvalidThisContextForHostObjectMethod, methodName));
                        return(JsValue.Undefined);
                    }

                    object[] processedArgs = GetHostItemMemberArguments(args);

                    var bestFitMethod = (MethodInfo)ReflectionHelpers.GetBestFitMethod(
                        methodCandidates, processedArgs);
                    if (bestFitMethod == null)
                    {
                        CreateAndSetReferenceError(string.Format(
                                                       Strings.Runtime_SuitableMethodOfHostObjectNotFound, methodName));
                        return(JsValue.Undefined);
                    }

                    ReflectionHelpers.FixArgumentTypes(ref processedArgs, bestFitMethod.GetParameters());

                    object result;

                    try
                    {
                        result = bestFitMethod.Invoke(obj, processedArgs);
                    }
                    catch (Exception e)
                    {
                        Exception exception        = UnwrapException(e);
                        var       wrapperException = exception as WrapperException;
                        JsValue   errorValue;

                        if (wrapperException != null)
                        {
                            errorValue = CreateErrorFromWrapperException(wrapperException);
                        }
                        else
                        {
                            string errorMessage = instance ?
                                                  string.Format(Strings.Runtime_HostObjectMethodInvocationFailed, methodName,
                                                                exception.Message)
                                                                :
                                                  string.Format(Strings.Runtime_HostTypeMethodInvocationFailed, methodName, typeName,
                                                                exception.Message)
                            ;
                            errorValue = JsErrorHelpers.CreateError(errorMessage);
                        }
                        JsContext.SetException(errorValue);

                        return(JsValue.Undefined);
                    }

                    JsValue resultValue = MapToScriptType(result);

                    return(resultValue);
                };
                nativeFunctions.Add(nativeFunction);

                JsValue methodValue = JsValue.CreateFunction(nativeFunction);
                typeValue.SetProperty(methodName, methodValue, true);
            }
        }
Ejemplo n.º 11
0
        private void ProjectFields(EmbeddedItem externalItem, EmbeddingObjectOptions options)
        {
            Type    type      = externalItem.HostType;
            object  obj       = externalItem.HostObject;
            JsValue typeValue = externalItem.ScriptValue;
            bool    instance  = externalItem.IsInstance;
            IList <JsNativeFunction> nativeFunctions = externalItem.NativeFunctions;

            string       typeName            = type.FullName;
            BindingFlags defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(instance);

            FieldInfo[] fields = type.GetFields(defaultBindingFlags).Where(options.IsMapped).ToArray();

            foreach (FieldInfo field in fields)
            {
                string fieldName = field.Name;

                JsValue descriptorValue = JsValue.CreateObject();
                descriptorValue.SetProperty("enumerable", JsValue.True, true);

                JsNativeFunction nativeGetFunction = (callee, isConstructCall, args, argCount, callbackData) =>
                {
                    if (instance && obj == null)
                    {
                        CreateAndSetError($"Context error while invoking getter '{fieldName}'.");
                        return(JsValue.Undefined);
                    }
                    object result;

                    try
                    {
                        result = field.GetValue(obj);
                    }
                    catch (Exception e)
                    {
                        Exception exception        = UnwrapException(e);
                        var       wrapperException = exception as JsException;
                        JsValue   errorValue;

                        if (wrapperException != null)
                        {
                            errorValue = CreateErrorFromWrapperException(wrapperException);
                        }
                        else
                        {
                            string errorMessage = instance ?
                                                  $"Error ocured while reading field '{fieldName}': {exception.Message}"
                                                                :
                                                  $"Erorr ocured while reading static field '{fieldName}' from type '{typeName}': {exception.Message}"
                            ;
                            errorValue = JsValue.CreateError(JsValue.FromString(errorMessage));
                        }
                        JsContext.SetException(errorValue);

                        return(JsValue.Undefined);
                    }

                    JsValue resultValue = MapToScriptType(result);

                    return(resultValue);
                };
                nativeFunctions.Add(nativeGetFunction);

                JsValue getMethodValue = JsValue.CreateFunction(nativeGetFunction);
                descriptorValue.SetProperty("get", getMethodValue, true);

                JsNativeFunction nativeSetFunction = (callee, isConstructCall, args, argCount, callbackData) =>
                {
                    if (instance && obj == null)
                    {
                        CreateAndSetError($"Invalid context got host object field {fieldName}.");
                        return(JsValue.Undefined);
                    }

                    object value = MapToHostType(args[1]);
                    ReflectionHelpers.FixFieldValueType(ref value, field);

                    try
                    {
                        field.SetValue(obj, value);
                    }
                    catch (Exception e)
                    {
                        Exception exception        = UnwrapException(e);
                        var       wrapperException = exception as JsException;
                        JsValue   errorValue;

                        if (wrapperException != null)
                        {
                            errorValue = CreateErrorFromWrapperException(wrapperException);
                        }
                        else
                        {
                            string errorMessage = instance ?
                                                  $"Failed to set value for hosts object field '{fieldName}': {exception.Message}"
                                                                :
                                                  $"Failed to set value for static type '{typeName}' field '{fieldName}': {exception.Message}"
                            ;
                            errorValue = JsValue.CreateError(JsValue.FromString(errorMessage));
                        }
                        JsContext.SetException(errorValue);

                        return(JsValue.Undefined);
                    }

                    return(JsValue.Undefined);
                };
                nativeFunctions.Add(nativeSetFunction);

                JsValue setMethodValue = JsValue.CreateFunction(nativeSetFunction);
                descriptorValue.SetProperty("set", setMethodValue, true);

                typeValue.DefineProperty(fieldName, descriptorValue);
            }
        }
Ejemplo n.º 12
0
        private void ProjectMethods(JsValue target, Type type, bool instance)
        {
            string       typeName            = type.FullName;
            BindingFlags defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(instance);

            MethodInfo[] methods = type.GetMethods(defaultBindingFlags);
            IEnumerable <IGrouping <string, MethodInfo> > methodGroups = methods.GroupBy(m => m.Name);

            foreach (IGrouping <string, MethodInfo> methodGroup in methodGroups)
            {
                string       methodName       = methodGroup.Key;
                MethodInfo[] methodCandidates = methodGroup.ToArray();

                JsNativeFunction nativeFunction = (callee, isConstructCall, args, argCount, callbackData) =>
                {
                    JsValue thisValue      = args[0];
                    JsValue undefinedValue = JsValue.Undefined;

                    object thisObj = null;

                    if (instance)
                    {
                        if (!thisValue.HasExternalData)
                        {
                            JsValue errorValue = JsErrorHelpers.CreateTypeError(
                                string.Format(Strings.Runtime_InvalidThisContextForHostObjectMethod, methodName));
                            JsErrorHelpers.SetException(errorValue);

                            return(undefinedValue);
                        }

                        thisObj = MapToHostType(thisValue);
                    }

                    object[] processedArgs = MapToHostType(args.Skip(1).ToArray());

                    var bestFitMethod = (MethodInfo)ReflectionHelpers.GetBestFitMethod(
                        methodCandidates, processedArgs);
                    if (bestFitMethod == null)
                    {
                        JsValue errorValue = JsErrorHelpers.CreateReferenceError(
                            string.Format(Strings.Runtime_SuitableMethodOfHostObjectNotFound, methodName));
                        JsErrorHelpers.SetException(errorValue);

                        return(undefinedValue);
                    }

                    ReflectionHelpers.FixArgumentTypes(ref processedArgs, bestFitMethod.GetParameters());

                    object result;

                    try
                    {
                        result = bestFitMethod.Invoke(thisObj, processedArgs);
                    }
                    catch (Exception e)
                    {
                        string errorMessage = instance ?
                                              string.Format(
                            Strings.Runtime_HostObjectMethodInvocationFailed, methodName, e.Message)
                            :
                                              string.Format(
                            Strings.Runtime_HostTypeMethodInvocationFailed, methodName, typeName, e.Message)
                        ;

                        JsValue errorValue = JsErrorHelpers.CreateError(errorMessage);
                        JsErrorHelpers.SetException(errorValue);

                        return(undefinedValue);
                    }

                    JsValue resultValue = MapToScriptType(result);

                    return(resultValue);
                };
                _nativeFunctions.Add(nativeFunction);

                JsValue methodValue = JsValue.CreateFunction(nativeFunction);
                target.SetProperty(methodName, methodValue, true);
            }
        }
Ejemplo n.º 13
0
        private void ProjectProperties(JsValue target, Type type, bool instance)
        {
            string       typeName            = type.FullName;
            BindingFlags defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(instance);

            PropertyInfo[] properties = type.GetProperties(defaultBindingFlags);

            foreach (PropertyInfo property in properties)
            {
                string propertyName = property.Name;

                JsValue descriptorValue = JsValue.CreateObject();
                descriptorValue.SetProperty("enumerable", JsValue.True, true);

                if (property.GetGetMethod() != null)
                {
                    JsNativeFunction nativeFunction = (callee, isConstructCall, args, argCount, callbackData) =>
                    {
                        JsValue thisValue      = args[0];
                        JsValue undefinedValue = JsValue.Undefined;

                        object thisObj = null;

                        if (instance)
                        {
                            if (!thisValue.HasExternalData)
                            {
                                JsValue errorValue = JsErrorHelpers.CreateTypeError(
                                    string.Format(Strings.Runtime_InvalidThisContextForHostObjectProperty, propertyName));
                                JsErrorHelpers.SetException(errorValue);

                                return(undefinedValue);
                            }

                            thisObj = MapToHostType(thisValue);
                        }

                        object result;

                        try
                        {
                            result = property.GetValue(thisObj, new object[0]);
                        }
                        catch (Exception e)
                        {
                            string errorMessage = instance ?
                                                  string.Format(
                                Strings.Runtime_HostObjectPropertyGettingFailed, propertyName, e.Message)
                                :
                                                  string.Format(
                                Strings.Runtime_HostTypePropertyGettingFailed, propertyName, typeName, e.Message)
                            ;

                            JsValue errorValue = JsErrorHelpers.CreateError(errorMessage);
                            JsErrorHelpers.SetException(errorValue);

                            return(undefinedValue);
                        }

                        JsValue resultValue = MapToScriptType(result);

                        return(resultValue);
                    };
                    _nativeFunctions.Add(nativeFunction);

                    JsValue getMethodValue = JsValue.CreateFunction(nativeFunction);
                    descriptorValue.SetProperty("get", getMethodValue, true);
                }

                if (property.GetSetMethod() != null)
                {
                    JsNativeFunction nativeFunction = (callee, isConstructCall, args, argCount, callbackData) =>
                    {
                        JsValue thisValue      = args[0];
                        JsValue undefinedValue = JsValue.Undefined;

                        object thisObj = null;

                        if (instance)
                        {
                            if (!thisValue.HasExternalData)
                            {
                                JsValue errorValue = JsErrorHelpers.CreateTypeError(
                                    string.Format(Strings.Runtime_InvalidThisContextForHostObjectProperty, propertyName));
                                JsErrorHelpers.SetException(errorValue);

                                return(undefinedValue);
                            }

                            thisObj = MapToHostType(thisValue);
                        }

                        object value = MapToHostType(args.Skip(1).First());
                        ReflectionHelpers.FixPropertyValueType(ref value, property);

                        try
                        {
                            property.SetValue(thisObj, value, new object[0]);
                        }
                        catch (Exception e)
                        {
                            string errorMessage = instance ?
                                                  string.Format(
                                Strings.Runtime_HostObjectPropertySettingFailed, propertyName, e.Message)
                                :
                                                  string.Format(
                                Strings.Runtime_HostTypePropertySettingFailed, propertyName, typeName, e.Message)
                            ;

                            JsValue errorValue = JsErrorHelpers.CreateError(errorMessage);
                            JsErrorHelpers.SetException(errorValue);

                            return(undefinedValue);
                        }

                        return(undefinedValue);
                    };
                    _nativeFunctions.Add(nativeFunction);

                    JsValue setMethodValue = JsValue.CreateFunction(nativeFunction);
                    descriptorValue.SetProperty("set", setMethodValue, true);
                }

                target.DefineProperty(propertyName, descriptorValue);
            }
        }
Ejemplo n.º 14
0
        private JsValue CreateConstructor(Type type)
        {
            TypeInfo     typeInfo            = type.GetTypeInfo();
            string       typeName            = type.FullName;
            BindingFlags defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(true);

            ConstructorInfo[] constructors = type.GetConstructors(defaultBindingFlags);

            JsNativeFunction nativeFunction = (callee, isConstructCall, args, argCount, callbackData) =>
            {
                JsValue resultValue;
                JsValue undefinedValue = JsValue.Undefined;

                object[] processedArgs = MapToHostType(args.Skip(1).ToArray());
                object   result;

                if (processedArgs.Length == 0 && typeInfo.IsValueType)
                {
                    result      = Activator.CreateInstance(type);
                    resultValue = MapToScriptType(result);

                    return(resultValue);
                }

                if (constructors.Length == 0)
                {
                    JsValue errorValue = JsErrorHelpers.CreateError(
                        string.Format(Strings.Runtime_HostTypeConstructorNotFound, typeName));
                    JsErrorHelpers.SetException(errorValue);

                    return(undefinedValue);
                }

                var bestFitConstructor = (ConstructorInfo)ReflectionHelpers.GetBestFitMethod(
                    constructors, processedArgs);
                if (bestFitConstructor == null)
                {
                    JsValue errorValue = JsErrorHelpers.CreateReferenceError(
                        string.Format(Strings.Runtime_SuitableConstructorOfHostTypeNotFound, typeName));
                    JsErrorHelpers.SetException(errorValue);

                    return(undefinedValue);
                }

                ReflectionHelpers.FixArgumentTypes(ref processedArgs, bestFitConstructor.GetParameters());

                try
                {
                    result = bestFitConstructor.Invoke(processedArgs);
                }
                catch (Exception e)
                {
                    JsValue errorValue = JsErrorHelpers.CreateError(
                        string.Format(Strings.Runtime_HostTypeConstructorInvocationFailed, typeName, e.Message));
                    JsErrorHelpers.SetException(errorValue);

                    return(undefinedValue);
                }

                resultValue = MapToScriptType(result);

                return(resultValue);
            };

            _nativeFunctions.Add(nativeFunction);

            JsValue constructorValue = JsValue.CreateFunction(nativeFunction);

            return(constructorValue);
        }
Ejemplo n.º 15
0
        private JsObject GeneratePrototype(Type type)
        {
            var ret        = new JsObject(GlobalScope);
            var methods    = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance).Where(m => m.GetCustomAttribute(typeof(JsMethodAttribute)) != null);
            var properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance).Where(m => m.GetCustomAttribute(typeof(JsPropertyAttribute)) != null);

            if (type == typeof(JsObject))
            {
                ret.JsProto = JsNull.Instance;
            }
            else
            {
                ret.JsProto = GetPrototype(type.BaseType);
            }
            foreach (var method in methods)
            {
                var methodProps = method.GetCustomAttribute <JsMethodAttribute>();
                var parameters  = method.GetParameters();

                if (method.ReturnType != typeof(JsValue))
                {
                    throw new JsInternalException("Method of native javascript type must have JsValue return type");
                }
                if (parameters.Length != 1 || parameters[0].ParameterType != typeof(LexicalEnvironment))
                {
                    throw new JsInternalException("Method of native javascript type must have one input paramter with LexicalEnvironment type");
                }
                var jsFunc = new JsNativeFunction(CreateMethodDelegate(method), methodProps.Name, GlobalScope);

                SetProperty(methodProps.Name, jsFunc);
            }
            foreach (var property in properties)
            {
                var propProps  = property.GetCustomAttribute <JsPropertyAttribute>();
                var setter     = property.SetMethod;
                var getter     = property.GetMethod;
                var jsProperty = new JsProperty(ret);

                if (property.PropertyType != typeof(JsValue))
                {
                    throw new JsInternalException("Javascript native property type must be JsValue");
                }
                if (propProps.IsInline)
                {
                    jsProperty.RawValue = (JsValue)getter.Invoke(ret, null);
                }
                else
                {
                    if (getter != null)
                    {
                        jsProperty.Getter = new JsNativeFunction(CreateGetterDelegate(getter), "", GlobalScope);
                    }
                    if (setter != null)
                    {
                        jsProperty.Setter = new JsNativeFunction(CreateSetterDelegate(setter), "", GlobalScope);
                    }
                }
                ret._properties.Add(propProps.Name, jsProperty);
            }
            return(ret);
        }