Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/OneScript.Core/OneScript.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
<ItemGroup>
<ProjectReference Include="..\OneScript.Language\OneScript.Language.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MessagePack" Version="3.1.4" />
</ItemGroup>

<PropertyGroup>
<PackageId>OneScript.CoreLib</PackageId>
Expand Down
8 changes: 8 additions & 0 deletions src/ScriptEngine.HostedScript/HostedScriptEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ public Process CreateProcess(IHostApplication host, SourceCode src)
return InitProcess(bslProcess, host, module);
}

public Process CreateProcess(IHostApplication host, IExecutableModule module)
{
Initialize();
SetGlobalEnvironment(host, module.Source);
var bslProcess = _engine.NewProcess();
return InitProcess(bslProcess, host, module);
}

private void DefineConstants(ICompilerFrontend compilerSvc)
{
var definitions = _workingConfig.PreprocessorDefinitions;
Expand Down
5 changes: 4 additions & 1 deletion src/ScriptEngine/Machine/Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This Source Code Form is subject to the terms of the
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/
using System;
using MessagePack;

namespace ScriptEngine.Machine
{
Expand Down Expand Up @@ -141,10 +142,12 @@ public enum OperationCode
ModuleInfo
}

[Serializable]
[MessagePackObjectAttribute]
public struct Command
{
[global::MessagePack.Key(0)]
public OperationCode Code;
[global::MessagePack.Key(1)]
public int Argument;

public override string ToString()
Expand Down
31 changes: 25 additions & 6 deletions src/ScriptEngine/Machine/MachineInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,8 @@ private void InitCommands()
#region Simple operations
private void PushVar(int arg)
{
if (arg < 0 || _module.VariableRefs == null || arg >= _module.VariableRefs.Count)
throw new ScriptException($"Invalid variable-ref index {arg} at instruction {_currentFrame?.InstructionPointer} in module {_module?.Source?.Location ?? "<unknown>"}");
var binding = _module.VariableRefs[arg];
var scope = _currentFrame.Scopes[binding.ScopeNumber];
_operationStack.Push(scope.Variables[binding.MemberNumber]);
Expand All @@ -668,6 +670,8 @@ private void PushVar(int arg)

private void PushConst(int arg)
{
if (arg < 0 || _module.Constants == null || arg >= _module.Constants.Count)
throw new ScriptException($"Invalid constant index {arg} at instruction {_currentFrame?.InstructionPointer} in module {_module?.Source?.Location ?? "<unknown>"}");
_operationStack.Push(_module.Constants[arg]);
NextInstruction();
}
Expand Down Expand Up @@ -698,12 +702,16 @@ private void PushNull(int arg)

private void PushLoc(int arg)
{
if (arg < 0 || _currentFrame == null || _currentFrame.Locals == null || arg >= _currentFrame.Locals.Length)
throw new ScriptException($"Invalid local index {arg} at instruction {_currentFrame?.InstructionPointer} in module {_module?.Source?.Location ?? "<unknown>"}");
_operationStack.Push(_currentFrame.Locals[arg]);
NextInstruction();
}

private void PushRef(int arg)
{
if (arg < 0 || _module.VariableRefs == null || arg >= _module.VariableRefs.Count)
throw new ScriptException($"Invalid variable-ref index {arg} at instruction {_currentFrame?.InstructionPointer} in module {_module?.Source?.Location ?? "<unknown>"}");
var binding = _module.VariableRefs[arg];
var scope = _currentFrame.Scopes[binding.ScopeNumber];
var reference = Variable.CreateContextPropertyReference(scope.Instance, binding.MemberNumber, "$stackvar");
Expand All @@ -713,17 +721,19 @@ private void PushRef(int arg)

private void LoadVar(int arg)
{
if (arg < 0 || _module.VariableRefs == null || arg >= _module.VariableRefs.Count)
throw new ScriptException($"Invalid variable-ref index {arg} at instruction {_currentFrame?.InstructionPointer} in module {_module?.Source?.Location ?? "<unknown>"}");
var binding = _module.VariableRefs[arg];
var scope = _currentFrame.Scopes[binding.ScopeNumber];
scope.Variables[binding.MemberNumber].Value = PopRawValue();
NextInstruction();
}

private void LoadLoc(int arg)
{
_currentFrame.Locals[arg].Value = PopRawValue();
NextInstruction();
}
private void LoadLoc(int arg)
{
_currentFrame.Locals[arg].Value = PopRawValue();
NextInstruction();
}

private void AssignRef(int arg)
{
Expand Down Expand Up @@ -995,7 +1005,10 @@ private void PushDefaultArg(int arg)
private void ResolveProp(int arg)
{
var objIValue = _operationStack.Pop();


if (arg < 0 || _module.Constants == null || arg >= _module.Constants.Count)
throw new ScriptException($"Invalid constant index {arg} at instruction {_currentFrame?.InstructionPointer} in module {_module?.Source?.Location ?? "<unknown>"}");

var context = objIValue.AsObject();
var propName = _module.Constants[arg].ToString(_process);
var propNum = context.GetPropertyNumber(propName);
Expand All @@ -1007,6 +1020,9 @@ private void ResolveProp(int arg)

private void ResolveMethodProc(int arg)
{
if (arg < 0 || _module.Constants == null || arg >= _module.Constants.Count)
throw new ScriptException($"Invalid constant index {arg} at instruction {_currentFrame?.InstructionPointer} in module {_module?.Source?.Location ?? "<unknown>"}");

PrepareContextCallArguments(arg, out IRuntimeContextInstance context, out int methodId, out IValue[] argValues);

context.CallAsProcedure(methodId, argValues, _process);
Expand All @@ -1015,6 +1031,9 @@ private void ResolveMethodProc(int arg)

private void ResolveMethodFunc(int arg)
{
if (arg < 0 || _module.Constants == null || arg >= _module.Constants.Count)
throw new ScriptException($"Invalid constant index {arg} at instruction {_currentFrame?.InstructionPointer} in module {_module?.Source?.Location ?? "<unknown>"}");

PrepareContextCallArguments(arg, out IRuntimeContextInstance context, out int methodId, out IValue[] argValues);

if (!context.DynamicMethodSignatures && context.GetMethodInfo(methodId).ReturnType == typeof(void))
Expand Down
91 changes: 91 additions & 0 deletions src/ScriptEngine/Machine/PrecompiledRuntimeModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*----------------------------------------------------------
This Source Code Form is subject to the terms of the
Mozilla Public License, v.2.0. If a copy of the MPL
was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/

using MessagePack;
using System.IO;
using System;
using System.Collections.Generic;
using OneScript.Contexts;
using OneScript.Execution;
using OneScript.Sources;

namespace ScriptEngine.Machine
{

[MessagePackObject]
public class PrecompiledRuntimeModule : IExecutableModule
{
[Key(0)]
public IList<BslAnnotationAttribute> ModuleAttributes { get; set; }

[Key(1)]
public IList<BslScriptFieldInfo> Fields { get; set; }

[Key(2)]
public IList<BslScriptPropertyInfo> Properties { get; set; }

[Key(3)]
public IList<BslScriptMethodInfo> Methods { get; set; }

[Key(4)]
public BslScriptMethodInfo ModuleBody { get; set; }

[Key(5)]
public SourceCode Source { get; set; }

[Key(6)]
public IDictionary<Type, object> Interfaces { get; set; }
}

public class ModuleSerializer
{
public static void SaveModule(IExecutableModule module, string filePath)
{
SaveModuleDto(module, filePath);
}

public static IExecutableModule LoadModule(string filePath)
{

if (!File.Exists(filePath))
throw new FileNotFoundException($"Precompiled module not found: {filePath}");

byte[] bytes = File.ReadAllBytes(filePath);

try
{
var dto = MessagePackSerializer.Deserialize<PrecompiledRuntimeModuleDto>(bytes);
if (dto != null)
{
return RuntimeModuleDtoMapper.FromDto(dto);
}
}
catch (MessagePack.MessagePackSerializationException)
{
// not DTO format, fall through to legacy deserialization
}

return MessagePackSerializer.Deserialize<PrecompiledRuntimeModule>(bytes);
}

public static void SaveModuleDto(IExecutableModule module, string filePath)
{
var dto = RuntimeModuleDtoMapper.ToDto(module);
byte[] bytes = MessagePackSerializer.Serialize(dto);
File.WriteAllBytes(filePath, bytes);
}

public static PrecompiledRuntimeModuleDto LoadModuleDto(string filePath)
{
if (!File.Exists(filePath))
throw new FileNotFoundException($"Precompiled module not found: {filePath}");

byte[] bytes = File.ReadAllBytes(filePath);
return MessagePackSerializer.Deserialize<PrecompiledRuntimeModuleDto>(bytes);
}
}
}
Loading