-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathcore.cpp
More file actions
129 lines (105 loc) · 3.48 KB
/
core.cpp
File metadata and controls
129 lines (105 loc) · 3.48 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
/**
* Core.cpp
*
* Implementation file for the context class
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2025 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 Php::Value
*/
Php::Value 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();
}
/**
* 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
*/
}