-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathcore.cpp
More file actions
146 lines (120 loc) · 3.83 KB
/
Copy pathcore.cpp
File metadata and controls
146 lines (120 loc) · 3.83 KB
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**
* Core.cpp
*
* Implementation file for the context class
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2025 - 2026 Copernica BV
*/
/**
* Dependencies
*/
#include "core.h"
#include "fromphp.h"
#include "php_variable.h"
#include "scope.h"
#include "php_object.h"
#include "php_exception.h"
#include "script.h"
#include "names.h"
/**
* Begin of namespace
*/
namespace JS {
/**
* Constructor
*/
Core::Core() : _platform(Platform::instance()), _isolate(this)
{
// when we access the isolate, we need a scope
v8::HandleScope scope(_isolate);
// create a context
v8::Local<v8::Context> context(v8::Context::New(_isolate));
// store pointer to ourselves
context->SetAlignedPointerInEmbedderData(0, this);
// we want to persist the context
_context.Reset(_isolate, context);
}
/**
* Given an isolate, it is possible to upgrade to the full context
* @return std::shared_ptr
*/
std::shared_ptr<Core> Core::upgrade(v8::Isolate *isolate)
{
// get the context
// @todo or should this sometimes be be GetCreationContext()????
auto context = isolate->GetCurrentContext();
// get the core object
auto *core = static_cast<Core *>(context->GetAlignedPointerFromEmbedderData(0));
// get the shared pointer
return core->shared_from_this();
}
/**
* Wrap a certain PHP object into a javascript object
* @param object MUST be an array or object!
* @return v8::Local<v8::Value>
*/
v8::Local<v8::Value> Core::wrap(const Php::Value &object)
{
// if the object is already known to be a JS\Object
auto *instance = PhpBase::unwrap(this, object);
// was this possible? then we reuse the original handle
if (instance != nullptr) return instance->handle();
// check the prototypes that we have
return _isolate.prototype(object).apply(object);
}
/**
* Assign a variable to the javascript context
* @param name name of property to assign required
* @param value value to be assigned
* @param attribytes property attributes
* @return bool
*/
bool Core::assign(const Php::Value &name, const Php::Value &value, const Php::Value &attributes)
{
// avoid that other contexts are assigned
if (value.instanceOf(Names::Context) || value.instanceOf(Names::Script)) return false;
// scope for the context
Scope scope(shared_from_this());
// retrieve the global object from the context
v8::Local<v8::Object> global(scope.global());
// the attribute for the newly assigned property
auto attribute = attributes.isNull() ? v8::None : static_cast<v8::PropertyAttribute>(attributes.numericValue());
// convert the property to a javascript name
v8::Local<v8::Value> property = FromPhp(_isolate, name.clone(Php::Type::String));
// store the value
v8::Maybe<bool> result = global->DefineOwnProperty(scope, property.As<v8::String>(), FromPhp(_isolate, value), attribute);
// check for success
return result.IsJust() && result.FromJust();
}
/**
* Reset the platform, start with a clean sheet
* @return bool
*/
void Core::reset()
{
// when we access the isolate, we need a scope
v8::HandleScope scope(_isolate);
// create a context
v8::Local<v8::Context> context(v8::Context::New(_isolate));
// we want to persist the context
_context.Reset(_isolate, context);
}
/**
* Parse a piece of javascript code
* @param source the code to execute
* @param timeout possible timeout in seconds
* @return Php::Value
* @throws Php::Exception
*/
Php::Value Core::evaluate(const Php::Value &source, const Php::Value &timeout)
{
// create a script
Script script(shared_from_this(), source.clone(Php::Type::String).rawValue());
// evaluate the script
return script.execute(timeout);
}
/**
* End of namespace
*/
}