-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathcore.cpp
More file actions
145 lines (118 loc) · 3.83 KB
/
Copy pathcore.cpp
File metadata and controls
145 lines (118 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
/**
* 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));
// we want to persist the context
_context.Reset(_isolate, context);
// symbol for linking js and php objects together
v8::Local<v8::Private> key = v8::Private::ForApi(_isolate, v8::String::NewFromUtf8Literal(_isolate, "js2php"));
// persist the key
_symbol.Reset(_isolate, key);
}
/**
* 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
for (auto &prototype : _templates)
{
// is this one compatible with the object
if (!prototype->matches(object)) continue;
// we can apply this prototype
return prototype->apply(object);
}
// we need a new template
_templates.emplace_back(new Template(_isolate, object));
// use it
return _templates.back()->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
*/
}