/// <summary> /// Constructs a new engine instance and allows customizing options. /// </summary> /// <remarks>The provided engine instance in callback is not guaranteed to be fully configured</remarks> public Engine(Action <Engine, Options> options) { _executionContexts = new ExecutionContextStack(2); Global = GlobalObject.CreateGlobalObject(this); Object = ObjectConstructor.CreateObjectConstructor(this); Function = FunctionConstructor.CreateFunctionConstructor(this); _callerCalleeArgumentsThrowerConfigurable = new GetSetPropertyDescriptor.ThrowerPropertyDescriptor(this, PropertyFlag.Configurable | PropertyFlag.CustomJsValue, "'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"); _callerCalleeArgumentsThrowerNonConfigurable = new GetSetPropertyDescriptor.ThrowerPropertyDescriptor(this, PropertyFlag.CustomJsValue, "'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"); Symbol = SymbolConstructor.CreateSymbolConstructor(this); Array = ArrayConstructor.CreateArrayConstructor(this); Map = MapConstructor.CreateMapConstructor(this); Set = SetConstructor.CreateSetConstructor(this); Iterator = IteratorConstructor.CreateIteratorConstructor(this); String = StringConstructor.CreateStringConstructor(this); RegExp = RegExpConstructor.CreateRegExpConstructor(this); Number = NumberConstructor.CreateNumberConstructor(this); Boolean = BooleanConstructor.CreateBooleanConstructor(this); Date = DateConstructor.CreateDateConstructor(this); Math = MathInstance.CreateMathObject(this); Json = JsonInstance.CreateJsonObject(this); Proxy = ProxyConstructor.CreateProxyConstructor(this); Reflect = ReflectInstance.CreateReflectObject(this); GlobalSymbolRegistry = new GlobalSymbolRegistry(); // Because the properties might need some of the built-in object // their configuration is delayed to a later step // trigger initialization Global.GetProperty(JsString.Empty); // this is implementation dependent, and only to pass some unit tests Global._prototype = Object.PrototypeObject; Object._prototype = Function.PrototypeObject; // create the global environment http://www.ecma-international.org/ecma-262/5.1/#sec-10.2.3 GlobalEnvironment = LexicalEnvironment.NewGlobalEnvironment(this, Global); // create the global execution context http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.1.1 EnterExecutionContext(GlobalEnvironment, GlobalEnvironment); Eval = new EvalFunctionInstance(this); Global.SetProperty(CommonProperties.Eval, new PropertyDescriptor(Eval, PropertyFlag.Configurable | PropertyFlag.Writable)); Options = new Options(); options?.Invoke(this, Options); // gather some options as fields for faster checks _isDebugMode = Options.IsDebugMode; _isStrict = Options.IsStrict; _constraints = Options._Constraints; _referenceResolver = Options.ReferenceResolver; _referencePool = new ReferencePool(); _argumentsInstancePool = new ArgumentsInstancePool(this); _jsValueArrayPool = new JsValueArrayPool(); if (Options._IsClrAllowed) { Global.SetProperty("System", new PropertyDescriptor(new NamespaceReference(this, "System"), PropertyFlag.AllForbidden)); Global.SetProperty("importNamespace", new PropertyDescriptor(new ClrFunctionInstance( this, "importNamespace", (thisObj, arguments) => new NamespaceReference(this, TypeConverter.ToString(arguments.At(0)))), PropertyFlag.AllForbidden)); } ClrTypeConverter = new DefaultTypeConverter(this); }