summaryrefslogtreecommitdiffstats
path: root/contrib/restricted/wavm/patches/0020-check-stack-depth.patch
blob: 889f579c877db112255e3493461f6d11a415abe5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
--- contrib/restricted/wavm/Lib/LLVMJIT/EmitFunction.cpp	(312badd895de32e15e6526c993b10a772fee96e0)
+++ contrib/restricted/wavm/Lib/LLVMJIT/EmitFunction.cpp	(index)
@@ -380,6 +380,9 @@ void EmitFunctionContext::emit()
 				emitLiteralIptr(offsetof(Runtime::Function, code), moduleContext.iptrType))});
 	}
 
+	emitRuntimeIntrinsic(
+		"checkCallStackDepth", FunctionType({}, {}, IR::CallingConvention::intrinsic), {});
+
 	// Decode the WebAssembly opcodes and emit LLVM IR for them.
 	OperatorDecoderStream decoder(functionDef.code);
 	UnreachableOpVisitor unreachableOpVisitor(*this);
--- contrib/restricted/wavm/Lib/Runtime/Context.cpp	(312badd895de32e15e6526c993b10a772fee96e0)
+++ contrib/restricted/wavm/Lib/Runtime/Context.cpp	(index)
@@ -61,6 +61,11 @@ Runtime::Context::~Context()
 
 Compartment* Runtime::getCompartment(const Context* context) { return context->compartment; }
 
+void Runtime::setCheckStackDepthCallback(Context* context, void (*callback)())
+{
+	context->setCheckStackDepthCallback(callback);
+}
+
 Context* Runtime::cloneContext(const Context* context, Compartment* newCompartment)
 {
 	// Create a new context and initialize its runtime data with the values from the source context.
@@ -70,6 +75,7 @@ Context* Runtime::cloneContext(const Context* context, Compartment* newCompartme
 		memcpy(clonedContext->runtimeData->mutableGlobals,
 			   context->runtimeData->mutableGlobals,
 			   maxMutableGlobals * sizeof(IR::UntaggedValue));
+		clonedContext->checkStackDepthCallback = context->checkStackDepthCallback;
 	}
 	return clonedContext;
 }
--- contrib/restricted/wavm/Lib/Runtime/RuntimePrivate.h	(312badd895de32e15e6526c993b10a772fee96e0)
+++ contrib/restricted/wavm/Lib/Runtime/RuntimePrivate.h	(index)
@@ -247,12 +247,15 @@ namespace WAVM { namespace Runtime {
 	{
 		Uptr id = UINTPTR_MAX;
 		struct ContextRuntimeData* runtimeData = nullptr;
+		void (*checkStackDepthCallback)() = nullptr;
 
 		Context(Compartment* inCompartment, std::string&& inDebugName)
 		: GCObject(ObjectKind::context, inCompartment, std::move(inDebugName))
 		{
 		}
 		~Context();
+
+		void setCheckStackDepthCallback(void (*callback)()) { checkStackDepthCallback = callback; }
 	};
 
 	struct Compartment : GCObject
--- contrib/restricted/wavm/Lib/Runtime/WAVMIntrinsics.cpp	(312badd895de32e15e6526c993b10a772fee96e0)
+++ contrib/restricted/wavm/Lib/Runtime/WAVMIntrinsics.cpp	(index)
@@ -70,6 +70,12 @@ WAVM_DEFINE_INTRINSIC_FUNCTION(wavmIntrinsics,
 				function->mutableData->debugName.c_str());
 }
 
+WAVM_DEFINE_INTRINSIC_FUNCTION(wavmIntrinsics, "checkCallStackDepth", void, checkCallStackDepth)
+{
+	Context* context = getContextFromRuntimeData(contextRuntimeData);
+	if(context->checkStackDepthCallback) { context->checkStackDepthCallback(); }
+}
+
 WAVM_DEFINE_INTRINSIC_FUNCTION(wavmIntrinsics, "debugBreak", void, debugBreak)
 {
 	Log::printf(Log::debug, "================== wavmIntrinsics.debugBreak\n");
--- contrib/restricted/wavm/Include/WAVM/Runtime/Runtime.h	(312badd895de32e15e6526c993b10a772fee96e0)
+++ contrib/restricted/wavm/Include/WAVM/Runtime/Runtime.h	(index)
@@ -546,6 +546,10 @@ namespace WAVM { namespace Runtime {
 	// Creates a new context, initializing its mutable global state from the given context.
 	WAVM_API Context* cloneContext(const Context* context, Compartment* newCompartment);
 
+	// Sets a callback to check call stack depth. The callback is invoked on function entry.
+	// Since stacks are user-provided, user must provide their own callback to check stack depth.
+	WAVM_API void setCheckStackDepthCallback(Context* context, void (*callback)());
+
 	//
 	// Foreign objects
 	//