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); } } } } } }
public ImmutablePrototypeObject(RuntimeObject constructor) : base(WellKnownObject.ObjectPrototype, constructor) { }
internal RuntimeFunctionInvocation(RuntimeFunction method, EcmaValue thisValue, EcmaValue[] arguments, RuntimeObject newTarget = null) { this.FunctionObject = method; this.Parent = current; this.ThisValue = thisValue; this.NewTarget = newTarget; this.arguments = arguments; this.previous = current; if (method.IsHomedMethod || method.IsDerivedConstructor) { this.Super = new SuperAccessor(this, method.HomeObject); } current = this; }
public static bool CreateMethodProperty(this RuntimeObject obj, EcmaPropertyKey propertyKey, EcmaValue value) { Guard.ArgumentNotNull(obj, "obj"); return(obj.DefineOwnProperty(propertyKey, new EcmaPropertyDescriptor(value, EcmaPropertyAttributes.DefaultMethodProperty))); }
public override bool SetPrototypeOf(RuntimeObject proto) { return(EcmaValue.Equals(GetPrototypeOf(), proto, EcmaValueComparison.SameValue)); }
protected override RuntimeObject ConstructThisValue(RuntimeObject newTarget) { return(RuntimeObject.CreateFromConstructor <EcmaObject>(this, WellKnownObject.ObjectPrototype)); }
public static bool IsWellknownObject(this RuntimeObject obj, WellKnownObject type) { Guard.ArgumentNotNull(obj, "obj"); return(obj == obj.Realm.GetRuntimeObject(type)); }
protected void SetPrototypeInternal(RuntimeObject proto) { proto.DefineOwnProperty(WellKnownProperty.Constructor, new EcmaPropertyDescriptor(this, EcmaPropertyAttributes.Configurable | EcmaPropertyAttributes.Writable)); DefineOwnProperty(WellKnownProperty.Prototype, new EcmaPropertyDescriptor(proto, EcmaPropertyAttributes.Writable)); }
public PrimitiveObject(EcmaValue value, WellKnownObject defaultProto, RuntimeObject constructor) : base(defaultProto, constructor) { this.value = value; }
protected virtual RuntimeObject ConstructThisValue(RuntimeObject newTarget) { throw new EcmaTypeErrorException(InternalString.Error.IllegalInvocation); }
public override IEnumerable <EcmaPropertyKey> GetOwnPropertyKeys() { RuntimeObject target = ThrowIfProxyRevoked(); RuntimeObject trap = handler.GetMethod(WellKnownProperty.OwnKeys); if (trap == null) { return(target.GetOwnPropertyKeys()); } EcmaValue resultArray = trap.Call(handler, target); Guard.ArgumentIsObject(resultArray); List <EcmaPropertyKey> list = new List <EcmaPropertyKey>(); long len = resultArray[WellKnownProperty.Length].ToLength(); for (long i = 0; i < len; i++) { EcmaValue value = resultArray[i]; if (!EcmaPropertyKey.IsPropertyKey(value)) { throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult); } EcmaPropertyKey key = EcmaPropertyKey.FromValue(value); if (list.Contains(key)) { throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult); } list.Add(key); } List <EcmaPropertyKey> targetKeys = new List <EcmaPropertyKey>(target.GetOwnPropertyKeys()); List <EcmaPropertyKey> targetConfigurableKeys = new List <EcmaPropertyKey>(); List <EcmaPropertyKey> targetNonConfigurableKeys = new List <EcmaPropertyKey>(); foreach (EcmaPropertyKey key in targetKeys) { EcmaPropertyDescriptor descriptor = target.GetOwnProperty(key); (descriptor.Configurable != false ? targetConfigurableKeys : targetNonConfigurableKeys).Add(key); } if (target.IsExtensible && targetNonConfigurableKeys.Count == 0) { return(list); } if (!targetNonConfigurableKeys.TrueForAll(list.Contains)) { throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult); } if (target.IsExtensible) { return(list); } if (!targetConfigurableKeys.TrueForAll(list.Contains)) { throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult); } if (!list.TrueForAll(targetKeys.Contains)) { throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult); } return(list); }
public RuntimeObjectProxy(RuntimeObject target, RuntimeObject handler) : base(WellKnownObject.ObjectPrototype) { Init(target, handler); }
internal SuperAccessor(RuntimeFunctionInvocation invocation, RuntimeObject homeObject) { this.invocation = invocation; this.homeObject = homeObject; }
internal void Init(GeneratorDelegate generator) { Guard.ArgumentNotNull(generator, "generator"); this.generator = generator; this.Source = "async function* () { [native code] }"; this.DefinePropertyOrThrow(WellKnownProperty.Prototype, new EcmaPropertyDescriptor(RuntimeObject.Create(this.Realm.GetRuntimeObject(WellKnownObject.AsyncGeneratorPrototype)), EcmaPropertyAttributes.Writable)); }