blob: 645ef8693aad91d2bbee707ce25a295fd3c59d43 (
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
81
|
#include <string.h>
#include <atomic>
#include <vector>
#include "RuntimePrivate.h"
#include "WAVM/Inline/Assert.h"
#include "WAVM/Inline/BasicTypes.h"
#include "WAVM/Platform/Memory.h"
#include "WAVM/Platform/RWMutex.h"
#include "WAVM/Runtime/Runtime.h"
#include "WAVM/RuntimeABI/RuntimeABI.h"
using namespace WAVM;
using namespace WAVM::Runtime;
Context* Runtime::createContext(Compartment* compartment, std::string&& debugName)
{
WAVM_ASSERT(compartment);
Context* context = new Context(compartment, std::move(debugName));
{
Platform::RWMutex::ExclusiveLock lock(compartment->mutex);
// Allocate an ID for the context in the compartment.
context->id = compartment->contexts.add(UINTPTR_MAX, context);
if(context->id == UINTPTR_MAX)
{
delete context;
return nullptr;
}
context->runtimeData = &compartment->runtimeData->contexts[context->id];
// Commit the page(s) for the context's runtime data.
if(!Platform::commitVirtualPages(
(U8*)context->runtimeData,
sizeof(ContextRuntimeData) >> Platform::getBytesPerPageLog2()))
{
delete context;
return nullptr;
}
Platform::registerVirtualAllocation(sizeof(ContextRuntimeData));
// Initialize the context's global data.
memcpy(context->runtimeData->mutableGlobals,
compartment->initialContextMutableGlobals,
maxMutableGlobals * sizeof(IR::UntaggedValue));
context->runtimeData->context = context;
}
return context;
}
Runtime::Context::~Context()
{
WAVM_ASSERT_RWMUTEX_IS_EXCLUSIVELY_LOCKED_BY_CURRENT_THREAD(compartment->mutex);
if(id != UINTPTR_MAX) { compartment->contexts.removeOrFail(id); }
Platform::decommitVirtualPages((U8*)runtimeData,
sizeof(ContextRuntimeData) >> Platform::getBytesPerPageLog2());
Platform::deregisterVirtualAllocation(sizeof(ContextRuntimeData));
}
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.
Context* clonedContext = createContext(newCompartment);
if(clonedContext)
{
memcpy(clonedContext->runtimeData->mutableGlobals,
context->runtimeData->mutableGlobals,
maxMutableGlobals * sizeof(IR::UntaggedValue));
clonedContext->checkStackDepthCallback = context->checkStackDepthCallback;
}
return clonedContext;
}
|