protected override ExpressionResult EvaluateInternal(EvaluationContext context) { var left = _left.GetValue(context).Value; var right = _right.GetValue(context).Value; JsValue result; if (context.OperatorOverloadingAllowed && TryOperatorOverloading(context, left, right, "op_Multiply", out var opResult)) { result = JsValue.FromObject(context.Engine, opResult); } else if (AreIntegerOperands(left, right)) { result = JsNumber.Create((long)left.AsInteger() * right.AsInteger()); } else { var leftNumeric = TypeConverter.ToNumeric(left); var rightNumeric = TypeConverter.ToNumeric(right); if (leftNumeric.IsNumber() && rightNumeric.IsNumber()) { result = JsNumber.Create(leftNumeric.AsNumber() * rightNumeric.AsNumber()); } else { AssertValidBigIntArithmeticOperands(context, leftNumeric, rightNumeric); result = JsBigInt.Create(leftNumeric.AsBigInt() * rightNumeric.AsBigInt()); } } return(NormalCompletion(result)); }
protected override ExpressionResult EvaluateInternal(EvaluationContext context) { var left = _left.GetValue(context).Value; var right = _right.GetValue(context).Value; if (context.OperatorOverloadingAllowed && TryOperatorOverloading(context, left, right, "op_Subtraction", out var opResult)) { return(NormalCompletion(JsValue.FromObject(context.Engine, opResult))); } JsValue number; left = TypeConverter.ToNumeric(left); right = TypeConverter.ToNumeric(right); if (AreIntegerOperands(left, right)) { number = JsNumber.Create((long)left.AsInteger() - right.AsInteger()); } else if (AreNonBigIntOperands(left, right)) { number = JsNumber.Create(left.AsNumber() - right.AsNumber()); } else { number = JsBigInt.Create(TypeConverter.ToBigInt(left) - TypeConverter.ToBigInt(right)); } return(NormalCompletion(number)); }
/// <summary> /// http://www.ecma-international.org/ecma-262/5.1/#sec-13.2 /// </summary> /// <param name="engine"></param> /// <param name="functionDeclaration"></param> /// <param name="scope"></param> /// <param name="strict"></param> public ScriptFunctionInstance( Engine engine, IFunction functionDeclaration, LexicalEnvironment scope, bool strict) : base(engine, functionDeclaration.Id?.Name ?? "", GetParameterNames(functionDeclaration), scope, strict) { _functionDeclaration = functionDeclaration; Extensible = true; Prototype = _engine.Function.PrototypeObject; _length = new PropertyDescriptor(JsNumber.Create(_formalParameters.Length), PropertyFlag.AllForbidden); var proto = new ObjectInstanceWithConstructor(engine, this) { Extensible = true, Prototype = _engine.Object.PrototypeObject }; _prototype = new PropertyDescriptor(proto, PropertyFlag.OnlyWritable); if (_functionDeclaration.Id != null) { DefineOwnProperty("name", new PropertyDescriptor(_functionDeclaration.Id.Name, PropertyFlag.None), false); } if (strict) { var thrower = engine.Function.ThrowTypeError; const PropertyFlag flags = PropertyFlag.EnumerableSet | PropertyFlag.ConfigurableSet; DefineOwnProperty("caller", new GetSetPropertyDescriptor(thrower, thrower, flags), false); DefineOwnProperty("arguments", new GetSetPropertyDescriptor(thrower, thrower, flags), false); } }
/// <summary> /// https://tc39.es/ecma262/#sec-get-dataview.prototype.bytelength /// </summary> private JsValue ByteLength(JsValue thisObj, JsValue[] arguments) { var o = thisObj as DataViewInstance; if (o is null) { ExceptionHelper.ThrowTypeError(_realm, "Method get DataView.prototype.byteLength called on incompatible receiver " + thisObj); } var buffer = o._viewedArrayBuffer; buffer.AssertNotDetached(); return(JsNumber.Create(o._byteLength)); }
public ClrFunctionInstance( Engine engine, string name, Func <JsValue, JsValue[], JsValue> func, int length = 0, PropertyFlag lengthFlags = PropertyFlag.AllForbidden) : base(engine, !(string.IsNullOrEmpty(name) || name.Trim() == "") ? new JsString(name) : null) { _func = func; _prototype = engine.Function.PrototypeObject; _length = lengthFlags == PropertyFlag.AllForbidden ? PropertyDescriptor.AllForbiddenDescriptor.ForNumber(length) : new PropertyDescriptor(JsNumber.Create(length), lengthFlags); }
public ClrFunctionInstance( Engine engine, string name, Func <JsValue, JsValue[], JsValue> func, int length = 0, PropertyFlag lengthFlags = PropertyFlag.AllForbidden) : base(engine, engine.Realm, name != null ? new JsString(name) : null) { _name = name; _func = func; _prototype = engine._originalIntrinsics.Function.PrototypeObject; _length = lengthFlags == PropertyFlag.AllForbidden ? PropertyDescriptor.AllForbiddenDescriptor.ForNumber(length) : new PropertyDescriptor(JsNumber.Create(length), lengthFlags); }
/// <summary> /// https://tc39.es/ecma262/#sec-arrayspeciescreate /// </summary> public ObjectInstance ArraySpeciesCreate(ObjectInstance originalArray, ulong length) { var isArray = originalArray.IsArray(); if (!isArray) { return(ArrayCreate(length)); } var c = originalArray.Get(CommonProperties.Constructor); if (c.IsConstructor) { var thisRealm = _engine.ExecutionContext.Realm; var realmC = GetFunctionRealm(c); if (!ReferenceEquals(thisRealm, realmC)) { if (ReferenceEquals(c, realmC.Intrinsics.Array)) { c = Undefined; } } } if (c.IsObject()) { c = c.Get(GlobalSymbolRegistry.Species); if (c.IsNull()) { c = Undefined; } } if (c.IsUndefined()) { return(ArrayCreate(length)); } if (!c.IsConstructor) { ExceptionHelper.ThrowTypeError(_realm, $"{c} is not a constructor"); } return(((IConstructor)c).Construct(new JsValue[] { JsNumber.Create(length) }, c)); }