Example #1
0
        private JsValue EvaluateModuleInternal(string code, string path, out JsValue moduleNamespace)
        {
            JsModuleRecord invalidModule  = JsModuleRecord.Invalid;
            string         modulePath     = path;
            string         moduleFullPath = GetModuleFullPath(invalidModule, modulePath);

            JsValue result;

            lock (_evaluationSynchronizer)
            {
                JsModuleRecord module = JsModuleRecord.Create(invalidModule, modulePath, moduleFullPath);
                module.SetFetchImportedModuleCallback(_fetchImportedModuleCallback);
                module.SetNotifyModuleReadyCallback(_notifyModuleReadyCallback);

                ModuleJob job = new ModuleJob
                {
                    Module    = module,
                    Script    = code,
                    SourceUrl = moduleFullPath,
                    IsParsed  = false
                };
                _moduleJobQueue.Enqueue(job);

                try
                {
                    result = EvaluateModulesTree(out moduleNamespace);
                    JsValue exception = module.Exception;

                    if (exception.IsValid)
                    {
                        JsValue metadata = JsValue.Invalid;
                        if (!JsContext.HasException)
                        {
                            JsErrorHelpers.SetException(exception);
                        }
                        metadata = JsContext.GetAndClearExceptionWithMetadata();

                        throw JsErrorHelpers.CreateScriptExceptionFromMetadata(metadata);
                    }
                }
                finally
                {
                    _moduleJobQueue.Clear();
                    module.Release();
                }
            }

            return(result);
        }
Example #2
0
        private JsValue CreateFunctionFromDelegate(Delegate value)
        {
            JsNativeFunction nativeFunction = (callee, isConstructCall, args, argCount, callbackData) =>
            {
                object[]        processedArgs  = MapToHostType(args.Skip(1).ToArray());
                ParameterInfo[] parameters     = value.GetMethodInfo().GetParameters();
                JsValue         undefinedValue = JsValue.Undefined;

                ReflectionHelpers.FixArgumentTypes(ref processedArgs, parameters);

                object result;

                try
                {
                    result = value.DynamicInvoke(processedArgs);
                }
                catch (Exception e)
                {
                    JsValue errorValue = JsErrorHelpers.CreateError(
                        string.Format(Strings.Runtime_HostDelegateInvocationFailed, e.Message));
                    JsErrorHelpers.SetException(errorValue);

                    return(undefinedValue);
                }

                JsValue resultValue = MapToScriptType(result);

                return(resultValue);
            };

            _nativeFunctions.Add(nativeFunction);

            JsValue functionValue = JsValue.CreateFunction(nativeFunction);

            return(functionValue);
        }
Example #3
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);
            }
        }
Example #4
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);
            }
        }
Example #5
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);
        }