public JintProjectionStateHandler(string source, bool enableContentTypeValidation, TimeSpan compilationTimeout, TimeSpan executionTimeout) { _enableContentTypeValidation = enableContentTypeValidation; _definitionBuilder = new SourceDefinitionBuilder(); _definitionBuilder.NoWhen(); _definitionBuilder.AllEvents(); TimeConstraint timeConstraint = new(compilationTimeout, executionTimeout); _engine = new Engine(opts => opts.Constraint(timeConstraint)); _engine.Global.RemoveOwnProperty("eval"); _state = JsValue.Undefined; _sharedState = JsValue.Undefined; _interpreterRuntime = new InterpreterRuntime(_engine, _definitionBuilder); timeConstraint.Compiling(); _engine.Execute(source); timeConstraint.Executing(); _json = _interpreterRuntime.SwitchToExecutionMode(); _engine.Global.FastAddProperty("emit", new ClrFunctionInstance(_engine, "emit", Emit, 4), true, false, true); _engine.Global.FastAddProperty("linkTo", new ClrFunctionInstance(_engine, "linkTo", LinkTo, 3), true, false, true); _engine.Global.FastAddProperty("linkStreamTo", new ClrFunctionInstance(_engine, "linkStreamTo", LinkStreamTo, 3), true, false, true); _engine.Global.FastAddProperty("copyTo", new ClrFunctionInstance(_engine, "copyTo", CopyTo, 3), true, false, true); _emitted = new List <EmittedEventEnvelope>(); }
/// <summary> /// Converts a simplified representation of an instance (used for JSON serialization) to a proper instance. /// </summary> /// <param name="jsonInstance">The instance in simplified presentation.</param> /// <returns>The converted instance.</returns> public static Instance FromJsonInstance(JsonInstance jsonInstance) { // Create instance with given parameters Instance instance = new Instance { Name = jsonInstance.Name }; instance.Containers.AddRange(jsonInstance.Containers.Select(c => new Container() { ID = c.ID, Mesh = new MeshCube() { Length = c.Length, Width = c.Width, Height = c.Height } })); instance.Pieces.AddRange(jsonInstance.Pieces.Select(p => { var convp = new VariablePiece() { ID = p.ID, }; if (p.Flags != null) { convp.SetFlags(p.Flags.Select(f => (f.FlagId, f.FlagValue))); } foreach (var comp in p.Cubes) { convp.AddComponent(comp.X, comp.Y, comp.Z, comp.Length, comp.Width, comp.Height); } return(convp); })); if (jsonInstance.Rules != null && jsonInstance.Rules.FlagRules != null) { instance.Rules = new RuleSet() { FlagRules = jsonInstance.Rules.FlagRules.Select(r => new FlagRule() { FlagId = r.FlagId, RuleType = r.RuleType, Parameter = r.Parameter, }).ToList(), } } ; // Seal it foreach (var container in instance.Containers) { container.Seal(); } foreach (var piece in instance.Pieces) { piece.Seal(); } // Return new instance return(instance); }
private static string?ConvertToStringHandlingNulls(JsonInstance json, JsValue value) { if (value.IsNull() || value.IsUndefined()) { return(null); } return(json.Stringify(JsValue.Undefined, new[] { value }).AsString()); }
static string?AsString(JsValue?value, JsonInstance json, bool formatForRaw) { return(value switch { JsBoolean b => b.AsBoolean() ? "true" : "false", JsString s => formatForRaw ? $"\"{s.AsString()}\"": s.AsString(), JsNumber n => n.AsNumber().ToString(CultureInfo.InvariantCulture), JsNull => null, JsUndefined => null, { } v => json.Stringify(JsValue.Undefined, new[] { v }).AsString(), _ => null });
/// <summary> /// Convert this instance into a simplified type for JSON serialization. /// </summary> /// <returns>The instance as a simplified representation.</returns> public JsonInstance ToJsonInstance() { // Convert to JSON representation var jsonInstance = new JsonInstance() { Name = Name, Containers = Containers.Select(c => new JsonContainer() { ID = c.ID, Length = c.Mesh.Length, Width = c.Mesh.Width, Height = c.Mesh.Height }).ToList(), Pieces = Pieces.Select(p => new JsonPiece() { ID = p.ID, Flags = p.GetFlags().Select(f => new JsonFlag() { FlagId = f.flag, FlagValue = f.value }).ToList(), Cubes = p.Original.Components.Select(c => new JsonCube() { X = c.RelPosition.X, Y = c.RelPosition.Y, Z = c.RelPosition.Z, Length = c.Length, Width = c.Width, Height = c.Height }).ToList() }).ToList(), Rules = new JsonRuleSet() { FlagRules = Rules.FlagRules.Select(r => new JsonFlagRule() { FlagId = r.FlagId, RuleType = r.RuleType, Parameter = r.Parameter }).ToList(), } }; // Return it return(jsonInstance); }
public Engine(Action <Options> options) { _executionContexts = new Stack <ExecutionContext>(); Global = GlobalObject.CreateGlobalObject(this); Object = ObjectConstructor.CreateObjectConstructor(this); Function = FunctionConstructor.CreateFunctionConstructor(this); Array = ArrayConstructor.CreateArrayConstructor(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); Error = ErrorConstructor.CreateErrorConstructor(this, "Error"); EvalError = ErrorConstructor.CreateErrorConstructor(this, "EvalError"); RangeError = ErrorConstructor.CreateErrorConstructor(this, "RangeError"); ReferenceError = ErrorConstructor.CreateErrorConstructor(this, "ReferenceError"); SyntaxError = ErrorConstructor.CreateErrorConstructor(this, "SyntaxError"); TypeError = ErrorConstructor.CreateErrorConstructor(this, "TypeError"); UriError = ErrorConstructor.CreateErrorConstructor(this, "URIError"); // Because the properties might need some of the built-in object // their configuration is delayed to a later step Global.Configure(); Object.Configure(); Object.PrototypeObject.Configure(); Function.Configure(); Function.PrototypeObject.Configure(); Array.Configure(); Array.PrototypeObject.Configure(); String.Configure(); String.PrototypeObject.Configure(); RegExp.Configure(); RegExp.PrototypeObject.Configure(); Number.Configure(); Number.PrototypeObject.Configure(); Boolean.Configure(); Boolean.PrototypeObject.Configure(); Date.Configure(); Date.PrototypeObject.Configure(); Math.Configure(); Json.Configure(); Error.Configure(); Error.PrototypeObject.Configure(); // create the global environment http://www.ecma-international.org/ecma-262/5.1/#sec-10.2.3 GlobalEnvironment = new LexicalEnvironment(); GlobalEnvironment.Setup(new ObjectEnvironmentRecord(this, Global, false), null); // create the global execution context http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.1.1 EnterExecutionContext(GlobalEnvironment, GlobalEnvironment, Global); Options = new Options(); if (options != null) { options(Options); } Eval = new EvalFunctionInstance(this, new string[0], LexicalEnvironment.NewDeclarativeEnvironment(this, ExecutionContext.LexicalEnvironment), StrictModeScope.IsStrictModeCode); Global.FastAddProperty("eval", Eval, true, false, true); _statements = new StatementInterpreter(this); _expressions = new ExpressionInterpreter(this); if (Options._IsClrAllowed) { Global.FastAddProperty("System", new NamespaceReference(this, "System"), false, false, false); Global.FastAddProperty("importNamespace", new ClrFunctionInstance(this, (thisObj, arguments) => { return(new NamespaceReference(this, TypeConverter.ToString(arguments.At(0)))); }), false, false, false); } ClrTypeConverter = new DefaultTypeConverter(this); BreakPoints = new List <BreakPoint>(); DebugHandler = new DebugHandler(this); }
/// <summary> /// Checks basic inconsistencies of the given instance and returns informative errors if found. /// </summary> /// <param name="instance">The instance to check.</param> /// <returns>Returns an error describing the identified problem or <code>null</code> if no problems were found.</returns> public static string Validate(JsonInstance instance) { // Check mandatory if (instance == null) { return("no instance provided"); } if ((instance.Containers?.Count ?? 0) <= 0) { return("no containers provided"); } if ((instance.Pieces?.Count ?? 0) <= 0) { return("no pieces provided"); } // Check containers var knownContainerIDs = new HashSet <int>(); foreach (var container in instance.Containers) { var added = knownContainerIDs.Add(container.ID); if (!added) { return($"container ID {container.ID} is duplicated"); } if (container.Length <= 0) { return($"invalid length {container.Length.ToString(CultureInfo.InvariantCulture)} of container {container.ID}"); } if (container.Width <= 0) { return($"invalid width {container.Width.ToString(CultureInfo.InvariantCulture)} of container {container.ID}"); } if (container.Height <= 0) { return($"invalid height {container.Height.ToString(CultureInfo.InvariantCulture)} of container {container.ID}"); } } // Check pieces var knownPieceIDs = new HashSet <int>(); foreach (var piece in instance.Pieces) { var added = knownPieceIDs.Add(piece.ID); if (!added) { return($"piece ID {piece.ID} is duplicated"); } if ((piece.Cubes?.Count ?? 0) <= 0) { return($"no cubes for piece {piece.ID} provided"); } foreach (var cube in piece.Cubes) { if (cube.Length <= 0) { return($"invalid length {cube.Length.ToString(CultureInfo.InvariantCulture)} of cube of piece {piece.ID}"); } if (cube.Width <= 0) { return($"invalid width {cube.Width.ToString(CultureInfo.InvariantCulture)} of cube of piece {piece.ID}"); } if (cube.Height <= 0) { return($"invalid height {cube.Height.ToString(CultureInfo.InvariantCulture)} of cube of piece {piece.ID}"); } if (cube.X < 0) { return($"invalid x-offset {cube.X.ToString(CultureInfo.InvariantCulture)} of cube of piece {piece.ID}"); } if (cube.Y < 0) { return($"invalid y-offset {cube.Y.ToString(CultureInfo.InvariantCulture)} of cube of piece {piece.ID}"); } if (cube.Z < 0) { return($"invalid z-offset {cube.Z.ToString(CultureInfo.InvariantCulture)} of cube of piece {piece.ID}"); } } } // No errors found return(null); }
public Engine(Action <Options> options) { _executionContexts = new ExecutionContextStack(); Global = GlobalObject.CreateGlobalObject(this); Object = ObjectConstructor.CreateObjectConstructor(this); Function = FunctionConstructor.CreateFunctionConstructor(this); 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); Error = ErrorConstructor.CreateErrorConstructor(this, "Error"); EvalError = ErrorConstructor.CreateErrorConstructor(this, "EvalError"); RangeError = ErrorConstructor.CreateErrorConstructor(this, "RangeError"); ReferenceError = ErrorConstructor.CreateErrorConstructor(this, "ReferenceError"); SyntaxError = ErrorConstructor.CreateErrorConstructor(this, "SyntaxError"); TypeError = ErrorConstructor.CreateErrorConstructor(this, "TypeError"); UriError = ErrorConstructor.CreateErrorConstructor(this, "URIError"); GlobalSymbolRegistry = new GlobalSymbolRegistry(); // Because the properties might need some of the built-in object // their configuration is delayed to a later step Global.Configure(); Object.Configure(); Object.PrototypeObject.Configure(); Symbol.Configure(); Symbol.PrototypeObject.Configure(); Function.Configure(); Function.PrototypeObject.Configure(); Array.Configure(); Array.PrototypeObject.Configure(); Map.Configure(); Map.PrototypeObject.Configure(); Set.Configure(); Set.PrototypeObject.Configure(); Iterator.Configure(); Iterator.PrototypeObject.Configure(); String.Configure(); String.PrototypeObject.Configure(); RegExp.Configure(); RegExp.PrototypeObject.Configure(); Number.Configure(); Number.PrototypeObject.Configure(); Boolean.Configure(); Boolean.PrototypeObject.Configure(); // Date.Configure(); // Date.PrototypeObject.Configure(); Math.Configure(); Json.Configure(); Error.Configure(); Error.PrototypeObject.Configure(); // create the global environment http://www.ecma-international.org/ecma-262/5.1/#sec-10.2.3 GlobalEnvironment = LexicalEnvironment.NewObjectEnvironment(this, Global, null, false); // create the global execution context http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.1.1 EnterExecutionContext(GlobalEnvironment, GlobalEnvironment, Global); Options = new Options(); options?.Invoke(Options); // gather some options as fields for faster checks _isDebugMode = Options.IsDebugMode; if (_isDebugMode) { MyAPIGateway.Utilities.ShowMessage("SpaceJS", "Debug mode enabled."); } _isStrict = Options.IsStrict; _maxStatements = Options._MaxStatements; _referenceResolver = Options.ReferenceResolver; _memoryLimit = Options._MemoryLimit; _runBeforeStatementChecks = (_maxStatements > 0 && _maxStatements < int.MaxValue) || Options._TimeoutInterval.Ticks > 0 || _memoryLimit > 0 || _isDebugMode; _referencePool = new ReferencePool(); _argumentsInstancePool = new ArgumentsInstancePool(this); _jsValueArrayPool = new JsValueArrayPool(); Eval = new EvalFunctionInstance(this, System.ArrayExt.Empty <string>(), LexicalEnvironment.NewDeclarativeEnvironment(this, ExecutionContext.LexicalEnvironment), StrictModeScope.IsStrictModeCode); Global.FastAddProperty("eval", Eval, true, false, true); _statements = new StatementInterpreter(this); _expressions = new ExpressionInterpreter(this); /* if (Options._IsClrAllowed) * { * Global.FastAddProperty("System", new NamespaceReference(this, "System"), false, false, false); * Global.FastAddProperty("importNamespace", new ClrFunctionInstance( * this, * "importNamespace", * (thisObj, arguments) => new NamespaceReference(this, TypeConverter.ToString(arguments.At(0)))), false, false, false); * } */ // ClrTypeConverter = new DefaultTypeConverter(this); }
private static XmlJsonInstance BuildJsonInstance(XPathNodeIterator iterator, JsonInstance parent, ref int nodeNumber) { while (iterator.MoveNext()) { XmlJsonInstance instance = null; XPathNavigator navigator = iterator.Current; if (navigator == null) { continue; } switch (navigator.NodeType) { case XPathNodeType.Root: case XPathNodeType.Namespace: case XPathNodeType.SignificantWhitespace: case XPathNodeType.ProcessingInstruction: case XPathNodeType.Whitespace: case XPathNodeType.Text: continue; case XPathNodeType.Attribute: XPathNodeIterator attributes = navigator.Select("@*"); while (attributes.MoveNext()) { if (attributes.Current == null) { continue; } XPathNavigator attribute = attributes.Current; string value = attribute.Value.Trim(); JsonInstance child = new XmlJsonInstance(attribute.Name, ObjectConverter.FromString(value, CultureInfo.InvariantCulture), nodeNumber, XPathNodeType.Attribute); child.Parent = instance; instance.Instances.Add(child); } //if (parent != null) { instance.Parent = parent; } //instances.Add(instance); break; case XPathNodeType.Element: string elementName = navigator.Name; bool directElement = (!navigator.HasAttributes && navigator.Select("child::node()[text()]").Count == 0); instance = new XmlJsonInstance(elementName, null, nodeNumber, XPathNodeType.Element); if ((navigator.SelectSingleNode("text()") == null)) // (navigator.IsEmptyElement || !navigator.HasChildren) && { } else { XPathNodeIterator textIterator = navigator.Select("text()"); string textValue = null; int textValueSpaceCount = -1; if (textIterator.Count > 0) { StringBuilder text = new StringBuilder(); while (textIterator.MoveNext()) { if (textIterator.Current == null) { continue; } text.Append(textIterator.Current.Value.Trim()); } textValue = text.ToString(); textValueSpaceCount = StringUtility.Count(textValue, ' '); } if (directElement && textValueSpaceCount == 0) { instance = new XmlJsonInstance(elementName, ObjectConverter.FromString(textValue, CultureInfo.InvariantCulture), nodeNumber); } else { JsonInstance child = new XmlJsonInstance("#text", ObjectConverter.FromString(textValue, CultureInfo.InvariantCulture), nodeNumber); child.Parent = instance; instance.Instances.Add(child); } } if (parent != null) { instance.Parent = parent; parent.Instances.Add(instance); } nodeNumber++; if (navigator.HasAttributes) { goto case XPathNodeType.Attribute; } break; } XPathNodeIterator children = navigator.Select("node()[not(self::text())]"); if (children.Count > 0) { BuildJsonInstance(children, instance, ref nodeNumber); } if (parent == null) { return(instance); } } return(null); }
/// <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); }