Пример #1
0
 private static bool IsValidReference(object value, out SharedObjectHandle handle)
 {
     if (value is Enum p1)
     {
         handle = RuntimeRealm.GetSharedObjectHandle(p1);
         return(true);
     }
     handle = default;
     return(false);
 }
Пример #2
0
        public static T CreateFromConstructor <T>(RuntimeObject constructor, SharedObjectHandle defaultProto) where T : RuntimeObject, new()
        {
            RuntimeObject proto = GetPrototypeFromConstructor(constructor, defaultProto);

            if (proto != null)
            {
                currentRealm = proto.Realm;
            }
            T obj;

            try {
                obj = new T();
            } finally {
                currentRealm = null;
            }
            obj.prototype = proto;
            return(obj);
        }
Пример #3
0
        public NativeRuntimeFunction(string name, MethodInfo method, bool containUseStrict, WellKnownObject proto)
            : base(proto)
        {
            Guard.ArgumentNotNull(method, "method");
            this.method = method;

            Type runtimeObjectType = null;

            if (method.HasAttribute(out IntrinsicConstructorAttribute attribute))
            {
                constraint        = attribute.Constraint;
                containUseStrict  = true;
                runtimeObjectType = attribute.ObjectType;
                if (attribute.Prototype is Enum protoEnum)
                {
                    defaultProto = RuntimeRealm.GetSharedObjectHandle(protoEnum);
                }
            }
            else if (method.HasAttribute(out IntrinsicMemberAttribute a2))
            {
                constraint       = NativeRuntimeFunctionConstraint.DenyConstruct;
                containUseStrict = true;
                if (name == null)
                {
                    name = a2.Name;
                }
            }
            else
            {
                SetPrototypeInternal(new EcmaObject());
            }
            if (name == null)
            {
                name = "";
            }
            this.Source = "function " + name + "() { [native code] }";
            InitProperty(name, GetFuncLength(method), containUseStrict);
            constructThisValue = runtimeObjectType == null || runtimeObjectType == typeof(EcmaObject) ? createFromConstructorDefault : createFromConstructor.MakeGenericMethod(runtimeObjectType);
        }
Пример #4
0
        public static RuntimeObject GetSpeciesConstructor(RuntimeObject obj, SharedObjectHandle defaultConstructor)
        {
            Guard.ArgumentNotNull(obj, "source");
            EcmaValue constructor = obj.Get(WellKnownProperty.Constructor);

            if (constructor == default)
            {
                return(obj.Realm.GetRuntimeObject(defaultConstructor));
            }
            Guard.ArgumentIsObject(constructor);
            constructor = constructor[WellKnownSymbol.Species];
            if (constructor.IsNullOrUndefined)
            {
                return(obj.Realm.GetRuntimeObject(defaultConstructor));
            }
            RuntimeObject runtimeObject = constructor.ToObject();

            if (runtimeObject.IsConstructor)
            {
                return(runtimeObject);
            }
            throw new EcmaTypeErrorException(InternalString.Error.NotConstructor);
        }
Пример #5
0
 protected RuntimeObject(object target)
     : base(target)
 {
     this.defaultProto = SharedObjectHandle.ObjectPrototype;
     this.Realm        = RuntimeRealm.Current;
 }
Пример #6
0
 protected RuntimeObject(SharedObjectHandle defaultProto, bool shared)
 {
     this.defaultProto = defaultProto;
     this.Realm        = shared ? RuntimeRealm.SharedRealm : RuntimeRealm.Current;
     this.prototype    = this.Realm.GetRuntimeObject(defaultProto);
 }
Пример #7
0
 public RuntimeObject(SharedObjectHandle defaultProto, RuntimeObject constructor)
 {
     this.defaultProto = defaultProto;
     this.prototype    = GetPrototypeFromConstructor(constructor, defaultProto);
     this.Realm        = prototype != null ? prototype.Realm : RuntimeRealm.Current;
 }
Пример #8
0
 public RuntimeObject(SharedObjectHandle defaultProto)
 {
     this.defaultProto = defaultProto;
     this.Realm        = currentRealm ?? RuntimeRealm.Current;
     this.prototype    = this.Realm.GetRuntimeObject(defaultProto);
 }
Пример #9
0
 public RuntimeObject()
 {
     this.defaultProto = SharedObjectHandle.ObjectPrototype;
     this.Realm        = currentRealm ?? RuntimeRealm.Current;
 }
Пример #10
0
        public static RuntimeObject GetPrototypeFromConstructor(RuntimeObject constructor, SharedObjectHandle defaultProto)
        {
            Guard.ArgumentNotNull(constructor, "constructor");
            if (!constructor.IsCallable)
            {
                throw new EcmaTypeErrorException(InternalString.Error.NotFunction);
            }
            EcmaValue proto = constructor.Get(WellKnownProperty.Prototype);

            if (proto.Type == EcmaValueType.Object)
            {
                return(proto.ToObject());
            }
            if (defaultProto != SharedObjectHandle.Null)
            {
                return(constructor.Realm.GetRuntimeObject(defaultProto));
            }
            return(null);
        }
Пример #11
0
 private static EcmaPropertyDescriptor CreateSharedObjectDescriptor(SharedObjectHandle handle, EcmaPropertyAttributes attributes)
 {
     return(new EcmaPropertyDescriptor(handle.ToValue(), attributes));
 }
Пример #12
0
        private void DefineIntrinsicObjectFromType(Type type, IntrinsicObjectAttribute typeAttr)
        {
            int objectIndex = ToValidIndex((Enum)typeAttr.ObjectType);
            Dictionary <EcmaPropertyKey, EcmaPropertyDescriptor> ht = properties[objectIndex];
            SharedObjectHandle handle = new SharedObjectHandle(this.Container.ID, objectIndex);

            if (IsValidReference(typeAttr.Prototype, out SharedObjectHandle protoHandle))
            {
                RuntimeObject thisObj = EnsureObject(objectIndex);
                thisObj.SetPrototypeOf(this.Realm.GetRuntimeObject(protoHandle));
            }
            if (typeAttr.Global)
            {
                globals[typeAttr.Name ?? type.Name] = CreateSharedObjectDescriptor(handle, EcmaPropertyAttributes.Configurable | EcmaPropertyAttributes.Writable);
            }
            foreach (MemberInfo member in type.GetMembers())
            {
                // special handling if the type defines an instrinsic contructor
                // replace the default object created from EnsureWellKnownObject to InstrincFunction
                if (member.HasAttribute(out IntrinsicConstructorAttribute ctorAttr))
                {
                    string ctorName = ctorAttr.Name ?? member.Name;
                    runtimeObjects[objectIndex] = CreateIntrinsicFunction(ctorName, (MethodInfo)member, ctorAttr.SuperClass as Enum, WellKnownObject.Global, ctorName);
                    if (IsValidReference(ctorAttr.Prototype, out SharedObjectHandle p1))
                    {
                        Dictionary <EcmaPropertyKey, EcmaPropertyDescriptor> hp = properties[ToValidIndex((Enum)ctorAttr.Prototype)];
                        ht[WellKnownProperty.Prototype]   = CreateSharedObjectDescriptor(p1, EcmaPropertyAttributes.None);
                        hp[WellKnownProperty.Constructor] = CreateSharedObjectDescriptor(handle, EcmaPropertyAttributes.Configurable | EcmaPropertyAttributes.Writable);
                    }
                    if (ctorAttr.Global)
                    {
                        globals[ctorName] = CreateSharedObjectDescriptor(handle, EcmaPropertyAttributes.DefaultMethodProperty);
                    }
                    continue;
                }

                object[] propAttrs = member.GetCustomAttributes(typeof(IntrinsicMemberAttribute), false);
                if (propAttrs.Length > 0)
                {
                    EcmaValue sharedValue = default;
                    if (member.HasAttribute(out AliasOfAttribute aliasOf) && aliasOf.ObjectType is Enum aliasOfType)
                    {
                        EcmaPropertyKey aliasOfKey = aliasOf.Name != null ? (EcmaPropertyKey)aliasOf.Name : aliasOf.Symbol;
                        if (!properties[ToValidIndex(aliasOfType)].TryGetValue(aliasOfKey, out EcmaPropertyDescriptor descriptor))
                        {
                            // for sake of simplicity the aliased target should be defined on intrinsic object with smaller WellKnownObject enum value
                            // to avoid the need of topological sort
                            throw new InvalidOperationException();
                        }
                        sharedValue = descriptor.Value;
                    }
                    if (sharedValue == default)
                    {
                        switch (member.MemberType)
                        {
                        case MemberTypes.Method:
                            IntrinsicMemberAttribute propAttr = (IntrinsicMemberAttribute)propAttrs[0];
                            EcmaPropertyKey          name     = GetNameFromMember(propAttr, member);
                            string runtimeName = (propAttr.Getter ? "get " : propAttr.Setter ? "set " : "") + (name.IsSymbol ? "[" + name.Symbol.Description + "]" : name.Name);
                            sharedValue = this.Container.Add(CreateIntrinsicFunction(runtimeName, (MethodInfo)member, null, typeAttr.ObjectType as Enum, name)).ToValue();
                            if (propAttr.Overridable)
                            {
                                overridables.Add(new SharedObjectKey(typeAttr.ObjectType, name), sharedValue.ToInt32() & 0xFFFF);
                            }
                            break;

                        case MemberTypes.Field:
                            object fieldValue = ((FieldInfo)member).GetValue(null);
                            sharedValue = IsValidReference(fieldValue, out SharedObjectHandle p1) ? p1.ToValue() : new EcmaValue(fieldValue);
                            break;

                        case MemberTypes.Property:
                            object propertyValue = ((PropertyInfo)member).GetValue(null, null);
                            sharedValue = IsValidReference(propertyValue, out SharedObjectHandle p2) ? p2.ToValue() : new EcmaValue(propertyValue);
                            break;
                        }
                    }
                    foreach (IntrinsicMemberAttribute propAttr in propAttrs)
                    {
                        EcmaPropertyKey name = GetNameFromMember(propAttr, member);
                        if (propAttr.Getter)
                        {
                            DefineIntrinsicAccessorProperty(ht, name, sharedValue, propAttr.Attributes, true);
                        }
                        else if (propAttr.Setter)
                        {
                            DefineIntrinsicAccessorProperty(ht, name, sharedValue, propAttr.Attributes, false);
                        }
                        else if (member.MemberType != MemberTypes.Method)
                        {
                            DefineIntrinsicDataProperty(ht, name, sharedValue, propAttr.Attributes);
                        }
                        else
                        {
                            DefineIntrinsicMethodProperty(ht, name, sharedValue, propAttr.Attributes);
                            if (propAttr.Global)
                            {
                                DefineIntrinsicMethodProperty(globals, name, sharedValue, propAttr.Attributes);
                            }
                        }
                    }
                }
            }
        }
Пример #13
0
        public RuntimeObject GetRuntimeObject(SharedObjectHandle handle)
        {
            int index = handle.HandleValue;

            return(GetSharedObject(index >> 16, index & 0xFFFF));
        }