Skip to content
This repository was archived by the owner on Mar 29, 2024. It is now read-only.

Commit ff43cc0

Browse files
committed
Add V8\UnboundScript class
1 parent 78585a3 commit ff43cc0

File tree

10 files changed

+582
-5
lines changed

10 files changed

+582
-5
lines changed

config.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ if test "$PHP_V8" != "no"; then
185185
src/php_v8_object_template.cc \
186186
src/php_v8_function_template.cc \
187187
src/php_v8_script.cc \
188+
src/php_v8_unbound_script.cc \
188189
src/php_v8_data.cc \
189190
src/php_v8_value.cc \
190191
src/php_v8_primitive.cc \

src/php_v8_script.cc

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "php_v8_script.h"
1818
#include "php_v8_script_origin.h"
19+
#include "php_v8_unbound_script.h"
1920
#include "php_v8_string.h"
2021
#include "php_v8_value.h"
2122
#include "php_v8.h"
@@ -186,13 +187,30 @@ static PHP_METHOD(V8Script, Run)
186187
v8::MaybeLocal<v8::Value> result = local_script->Run(context);
187188

188189
PHP_V8_MAYBE_CATCH(php_v8_script->php_v8_context, try_catch);
189-
PHP_V8_THROW_VALUE_EXCEPTION_WHEN_EMPTY(result, "Failed to create run script");
190+
PHP_V8_THROW_VALUE_EXCEPTION_WHEN_EMPTY(result, "Failed to run script");
190191

191192
v8::Local<v8::Value> local_result = result.ToLocalChecked();
192193

193194
php_v8_get_or_create_value(return_value, local_result, isolate);
194195
}
195196

197+
static PHP_METHOD(V8Script, GetUnboundScript)
198+
{
199+
if (zend_parse_parameters_none() == FAILURE) {
200+
return;
201+
}
202+
203+
PHP_V8_FETCH_SCRIPT_WITH_CHECK(getThis(), php_v8_script);
204+
PHP_V8_ENTER_STORED_ISOLATE(php_v8_script);
205+
PHP_V8_ENTER_STORED_CONTEXT(php_v8_script);
206+
207+
v8::Local<v8::Script> local_script = php_v8_script_get_local(isolate, php_v8_script);
208+
209+
v8::Local<v8::UnboundScript> unbound_script = local_script->GetUnboundScript();
210+
211+
php_v8_create_unbound_script(return_value, php_v8_script->php_v8_isolate, unbound_script);
212+
}
213+
196214

197215
ZEND_BEGIN_ARG_INFO_EX(arginfo_v8_script___construct, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 2)
198216
ZEND_ARG_OBJ_INFO(0, context, V8\\Context, 0)
@@ -210,13 +228,17 @@ PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_v8_script_Run, ZEND_RETURN
210228
ZEND_ARG_OBJ_INFO(0, context, V8\\Context, 0)
211229
ZEND_END_ARG_INFO()
212230

231+
PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_v8_script_GetUnboundScript, ZEND_RETURN_VALUE, 0, V8\\UnboundScript, 0)
232+
ZEND_END_ARG_INFO()
233+
213234

214235
static const zend_function_entry php_v8_script_methods[] = {
215236
PHP_ME(V8Script, __construct, arginfo_v8_script___construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
216237
PHP_ME(V8Script, GetIsolate, arginfo_v8_script_GetIsolate, ZEND_ACC_PUBLIC)
217238
PHP_ME(V8Script, GetContext, arginfo_v8_script_GetContext, ZEND_ACC_PUBLIC)
218239

219240
PHP_ME(V8Script, Run, arginfo_v8_script_Run, ZEND_ACC_PUBLIC)
241+
PHP_ME(V8Script, GetUnboundScript, arginfo_v8_script_GetUnboundScript, ZEND_ACC_PUBLIC)
220242

221243
PHP_FE_END
222244
};

src/php_v8_unbound_script.cc

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
/*
2+
* This file is part of the pinepain/php-v8 PHP extension.
3+
*
4+
* Copyright (c) 2015-2017 Bogdan Padalko <pinepain@gmail.com>
5+
*
6+
* Licensed under the MIT license: http://opensource.org/licenses/MIT
7+
*
8+
* For the full copyright and license information, please view the
9+
* LICENSE file that was distributed with this source or visit
10+
* http://opensource.org/licenses/MIT
11+
*/
12+
13+
#ifdef HAVE_CONFIG_H
14+
#include "config.h"
15+
#endif
16+
17+
#include "php_v8_unbound_script.h"
18+
#include "php_v8_script.h"
19+
#include "php_v8_string.h"
20+
#include "php_v8_value.h"
21+
#include "php_v8_context.h"
22+
#include "php_v8.h"
23+
24+
zend_class_entry* php_v8_unbound_script_class_entry;
25+
#define this_ce php_v8_unbound_script_class_entry
26+
27+
static zend_object_handlers php_v8_unbound_script_object_handlers;
28+
29+
30+
v8::Local<v8::UnboundScript> php_v8_unbound_script_get_local(v8::Isolate *isolate, php_v8_unbound_script_t *php_v8_unbound_script) {
31+
return v8::Local<v8::UnboundScript>::New(isolate, *php_v8_unbound_script->persistent);
32+
}
33+
34+
php_v8_unbound_script_t * php_v8_unbound_script_fetch_object(zend_object *obj) {
35+
return (php_v8_unbound_script_t *)((char *)obj - XtOffsetOf(php_v8_unbound_script_t, std));
36+
}
37+
38+
php_v8_unbound_script_t * php_v8_create_unbound_script(zval *return_value, php_v8_isolate_t *php_v8_isolate, v8::Local<v8::UnboundScript> unbound_script) {
39+
assert(!unbound_script.IsEmpty());
40+
41+
object_init_ex(return_value, this_ce);
42+
43+
PHP_V8_FETCH_UNBOUND_SCRIPT_INTO(return_value, php_v8_unbound_script);
44+
PHP_V8_UNBOUND_SCRIPT_STORE_ISOLATE(return_value, &php_v8_isolate->this_ptr)
45+
PHP_V8_STORE_POINTER_TO_ISOLATE(php_v8_unbound_script, php_v8_isolate);
46+
47+
php_v8_unbound_script->persistent->Reset(php_v8_isolate->isolate, unbound_script);
48+
49+
return php_v8_unbound_script;
50+
}
51+
52+
53+
static void php_v8_unbound_script_free(zend_object *object)
54+
{
55+
php_v8_unbound_script_t *php_v8_unbound_script = php_v8_unbound_script_fetch_object(object);
56+
57+
if (php_v8_unbound_script->persistent) {
58+
if (PHP_V8_ISOLATE_HAS_VALID_HANDLE(php_v8_unbound_script)) {
59+
php_v8_unbound_script->persistent->Reset();
60+
}
61+
delete php_v8_unbound_script->persistent;
62+
}
63+
64+
zend_object_std_dtor(&php_v8_unbound_script->std);
65+
}
66+
67+
static zend_object * php_v8_unbound_script_ctor(zend_class_entry *ce)
68+
{
69+
php_v8_unbound_script_t *php_v8_unbound_script;
70+
71+
php_v8_unbound_script = (php_v8_unbound_script_t *) ecalloc(1, sizeof(php_v8_unbound_script_t) + zend_object_properties_size(ce));
72+
73+
zend_object_std_init(&php_v8_unbound_script->std, ce);
74+
object_properties_init(&php_v8_unbound_script->std, ce);
75+
76+
php_v8_unbound_script->persistent = new v8::Persistent<v8::UnboundScript>();
77+
78+
php_v8_unbound_script->std.handlers = &php_v8_unbound_script_object_handlers;
79+
80+
return &php_v8_unbound_script->std;
81+
}
82+
83+
static PHP_METHOD(V8UnboundScript, __construct)
84+
{
85+
if (zend_parse_parameters_none() == FAILURE) {
86+
return;
87+
}
88+
89+
PHP_V8_THROW_EXCEPTION("V8\\UnboundScript::__construct() should not be called. Use other methods which yield V8\\UnboundScript object.")
90+
}
91+
92+
static PHP_METHOD(V8UnboundScript, GetIsolate)
93+
{
94+
zval rv;
95+
96+
if (zend_parse_parameters_none() == FAILURE) {
97+
return;
98+
}
99+
100+
PHP_V8_FETCH_UNBOUND_SCRIPT_WITH_CHECK(getThis(), php_v8_unbound_script);
101+
102+
RETVAL_ZVAL(PHP_V8_UNBOUND_SCRIPT_READ_ISOLATE(getThis()), 1, 0);
103+
}
104+
105+
static PHP_METHOD(V8UnboundScript, BindToContext)
106+
{
107+
zval *php_v8_context_zv;
108+
109+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &php_v8_context_zv) == FAILURE) {
110+
return;
111+
}
112+
113+
PHP_V8_FETCH_UNBOUND_SCRIPT_WITH_CHECK(getThis(), php_v8_unbound_script);
114+
PHP_V8_CONTEXT_FETCH_WITH_CHECK(php_v8_context_zv, php_v8_context);
115+
116+
PHP_V8_DATA_ISOLATES_CHECK(php_v8_unbound_script, php_v8_context);
117+
118+
PHP_V8_ENTER_STORED_ISOLATE(php_v8_context);
119+
PHP_V8_ENTER_CONTEXT(php_v8_context);
120+
121+
v8::Local<v8::UnboundScript> local_unbound_script = php_v8_unbound_script_get_local(isolate, php_v8_unbound_script);
122+
v8::Local<v8::Script> local_script = local_unbound_script->BindToCurrentContext();
123+
124+
php_v8_create_script(return_value, local_script, php_v8_context);
125+
}
126+
127+
static PHP_METHOD(V8UnboundScript, GetId)
128+
{
129+
if (zend_parse_parameters_none() == FAILURE) {
130+
return;
131+
}
132+
133+
PHP_V8_FETCH_UNBOUND_SCRIPT_WITH_CHECK(getThis(), php_v8_unbound_script);
134+
PHP_V8_ENTER_STORED_ISOLATE(php_v8_unbound_script);
135+
136+
v8::Local<v8::UnboundScript> local_unbound_script = php_v8_unbound_script_get_local(isolate, php_v8_unbound_script);
137+
138+
RETURN_LONG(static_cast<zend_long>(local_unbound_script->GetId()));
139+
}
140+
141+
static PHP_METHOD(V8UnboundScript, GetScriptName)
142+
{
143+
if (zend_parse_parameters_none() == FAILURE) {
144+
return;
145+
}
146+
147+
PHP_V8_FETCH_UNBOUND_SCRIPT_WITH_CHECK(getThis(), php_v8_unbound_script);
148+
PHP_V8_ENTER_STORED_ISOLATE(php_v8_unbound_script);
149+
150+
v8::Local<v8::UnboundScript> local_unbound_script = php_v8_unbound_script_get_local(isolate, php_v8_unbound_script);
151+
152+
php_v8_get_or_create_value(return_value, local_unbound_script->GetScriptName(), isolate);
153+
}
154+
155+
static PHP_METHOD(V8UnboundScript, GetSourceURL)
156+
{
157+
if (zend_parse_parameters_none() == FAILURE) {
158+
return;
159+
}
160+
161+
PHP_V8_FETCH_UNBOUND_SCRIPT_WITH_CHECK(getThis(), php_v8_unbound_script);
162+
PHP_V8_ENTER_STORED_ISOLATE(php_v8_unbound_script);
163+
164+
v8::Local<v8::UnboundScript> local_unbound_script = php_v8_unbound_script_get_local(isolate, php_v8_unbound_script);
165+
166+
php_v8_get_or_create_value(return_value, local_unbound_script->GetSourceURL(), isolate);
167+
}
168+
169+
static PHP_METHOD(V8UnboundScript, GetSourceMappingURL)
170+
{
171+
if (zend_parse_parameters_none() == FAILURE) {
172+
return;
173+
}
174+
175+
PHP_V8_FETCH_UNBOUND_SCRIPT_WITH_CHECK(getThis(), php_v8_unbound_script);
176+
PHP_V8_ENTER_STORED_ISOLATE(php_v8_unbound_script);
177+
178+
v8::Local<v8::UnboundScript> local_unbound_script = php_v8_unbound_script_get_local(isolate, php_v8_unbound_script);
179+
180+
php_v8_get_or_create_value(return_value, local_unbound_script->GetSourceMappingURL(), isolate);
181+
}
182+
183+
static PHP_METHOD(V8UnboundScript, GetLineNumber)
184+
{
185+
zend_long code_pos = 0;
186+
187+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &code_pos) == FAILURE) {
188+
return;
189+
}
190+
191+
PHP_V8_CHECK_CODE_POS_RANGE(code_pos, "Value is out of range");
192+
193+
PHP_V8_FETCH_UNBOUND_SCRIPT_WITH_CHECK(getThis(), php_v8_unbound_script);
194+
PHP_V8_ENTER_STORED_ISOLATE(php_v8_unbound_script);
195+
196+
v8::Local<v8::UnboundScript> local_unbound_script = php_v8_unbound_script_get_local(isolate, php_v8_unbound_script);
197+
198+
RETURN_LONG(static_cast<zend_long>(local_unbound_script->GetLineNumber(static_cast<int>(code_pos))));
199+
}
200+
201+
202+
ZEND_BEGIN_ARG_INFO_EX(arginfo_v8_unbound_script___construct, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0)
203+
ZEND_END_ARG_INFO()
204+
205+
PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_v8_unbound_script_GetIsolate, ZEND_RETURN_VALUE, 0, V8\\Isolate, 0)
206+
ZEND_END_ARG_INFO()
207+
208+
PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_v8_unbound_script_BindToContext, ZEND_RETURN_VALUE, 1, V8\\Script, 0)
209+
ZEND_ARG_OBJ_INFO(0, context, V8\\Context, 0)
210+
ZEND_END_ARG_INFO()
211+
212+
PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_v8_unbound_script_GetId, ZEND_RETURN_VALUE, 0, IS_LONG, 0)
213+
ZEND_END_ARG_INFO()
214+
215+
PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_v8_unbound_script_GetScriptName, ZEND_RETURN_VALUE, 0, V8\\Value, 0)
216+
ZEND_END_ARG_INFO()
217+
218+
PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_v8_unbound_script_GetSourceURL, ZEND_RETURN_VALUE, 0, V8\\Value, 0)
219+
ZEND_END_ARG_INFO()
220+
221+
PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_v8_unbound_script_GetSourceMappingURL, ZEND_RETURN_VALUE, 0, V8\\Value, 0)
222+
ZEND_END_ARG_INFO()
223+
224+
PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_v8_unbound_script_GetLineNumber, ZEND_RETURN_VALUE, 1, IS_LONG, 0)
225+
ZEND_ARG_TYPE_INFO(0, code_pos, IS_LONG, 0)
226+
ZEND_END_ARG_INFO()
227+
228+
229+
static const zend_function_entry php_v8_unbound_script_methods[] = {
230+
PHP_ME(V8UnboundScript, __construct, arginfo_v8_unbound_script___construct, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
231+
PHP_ME(V8UnboundScript, GetIsolate, arginfo_v8_unbound_script_GetIsolate, ZEND_ACC_PUBLIC)
232+
PHP_ME(V8UnboundScript, BindToContext, arginfo_v8_unbound_script_BindToContext, ZEND_ACC_PUBLIC)
233+
PHP_ME(V8UnboundScript, GetId, arginfo_v8_unbound_script_GetId, ZEND_ACC_PUBLIC)
234+
PHP_ME(V8UnboundScript, GetScriptName, arginfo_v8_unbound_script_GetScriptName, ZEND_ACC_PUBLIC)
235+
PHP_ME(V8UnboundScript, GetSourceURL, arginfo_v8_unbound_script_GetSourceURL, ZEND_ACC_PUBLIC)
236+
PHP_ME(V8UnboundScript, GetSourceMappingURL, arginfo_v8_unbound_script_GetSourceMappingURL, ZEND_ACC_PUBLIC)
237+
PHP_ME(V8UnboundScript, GetLineNumber, arginfo_v8_unbound_script_GetLineNumber, ZEND_ACC_PUBLIC)
238+
239+
PHP_FE_END
240+
};
241+
242+
243+
PHP_MINIT_FUNCTION(php_v8_unbound_script)
244+
{
245+
zend_class_entry ce;
246+
247+
INIT_NS_CLASS_ENTRY(ce, PHP_V8_NS, "UnboundScript", php_v8_unbound_script_methods);
248+
this_ce = zend_register_internal_class(&ce);
249+
this_ce->create_object = php_v8_unbound_script_ctor;
250+
251+
zend_declare_property_null(this_ce, ZEND_STRL("isolate"), ZEND_ACC_PRIVATE);
252+
zend_declare_class_constant_long(this_ce, ZEND_STRL("kNoScriptId"), v8::UnboundScript::kNoScriptId);
253+
254+
memcpy(&php_v8_unbound_script_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
255+
256+
php_v8_unbound_script_object_handlers.offset = XtOffsetOf(php_v8_unbound_script_t, std);
257+
php_v8_unbound_script_object_handlers.free_obj = php_v8_unbound_script_free;
258+
259+
return SUCCESS;
260+
}

src/php_v8_unbound_script.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* This file is part of the pinepain/php-v8 PHP extension.
3+
*
4+
* Copyright (c) 2015-2017 Bogdan Padalko <pinepain@gmail.com>
5+
*
6+
* Licensed under the MIT license: http://opensource.org/licenses/MIT
7+
*
8+
* For the full copyright and license information, please view the
9+
* LICENSE file that was distributed with this source or visit
10+
* http://opensource.org/licenses/MIT
11+
*/
12+
13+
#ifndef PHP_V8_UNBOUND_SCRIPT_H
14+
#define PHP_V8_UNBOUND_SCRIPT_H
15+
16+
typedef struct _php_v8_unbound_script_t php_v8_unbound_script_t;
17+
18+
#include "php_v8_exception.h"
19+
#include "php_v8_isolate.h"
20+
#include <v8.h>
21+
22+
extern "C" {
23+
#include "php.h"
24+
25+
#ifdef ZTS
26+
#include "TSRM.h"
27+
#endif
28+
}
29+
30+
extern zend_class_entry *php_v8_unbound_script_class_entry;
31+
32+
extern v8::Local<v8::UnboundScript> php_v8_unbound_script_get_local(v8::Isolate *isolate, php_v8_unbound_script_t *php_v8_unbound_script);
33+
extern php_v8_unbound_script_t * php_v8_unbound_script_fetch_object(zend_object *obj);
34+
extern php_v8_unbound_script_t * php_v8_create_unbound_script(zval *return_value, php_v8_isolate_t *php_v8_isolate, v8::Local<v8::UnboundScript> unbound_script);
35+
36+
37+
#define PHP_V8_FETCH_UNBOUND_SCRIPT(zv) php_v8_unbound_script_fetch_object(Z_OBJ_P(zv))
38+
#define PHP_V8_FETCH_UNBOUND_SCRIPT_INTO(pzval, into) php_v8_unbound_script_t *(into) = PHP_V8_FETCH_UNBOUND_SCRIPT((pzval))
39+
40+
#define PHP_V8_EMPTY_UNBOUND_SCRIPT_MSG "UnboundScript" PHP_V8_EMPTY_HANDLER_MSG_PART
41+
#define PHP_V8_CHECK_EMPTY_UNBOUND_SCRIPT_HANDLER(val) PHP_V8_CHECK_EMPTY_HANDLER((val), PHP_V8_EMPTY_UNBOUND_SCRIPT_MSG)
42+
43+
#define PHP_V8_FETCH_UNBOUND_SCRIPT_WITH_CHECK(pzval, into) \
44+
PHP_V8_FETCH_UNBOUND_SCRIPT_INTO(pzval, into); \
45+
PHP_V8_CHECK_EMPTY_UNBOUND_SCRIPT_HANDLER(into);
46+
47+
48+
#define PHP_V8_UNBOUND_SCRIPT_STORE_ISOLATE(to_zval, isolate_zv) zend_update_property(php_v8_unbound_script_class_entry, (to_zval), ZEND_STRL("isolate"), (isolate_zv));
49+
#define PHP_V8_UNBOUND_SCRIPT_READ_ISOLATE(from_zval) zend_read_property(php_v8_unbound_script_class_entry, (from_zval), ZEND_STRL("isolate"), 0, &rv)
50+
51+
#define PHP_V8_CHECK_CODE_POS_RANGE(val, message) \
52+
if ((val) > INT_MAX || (val) < INT_MIN) { \
53+
PHP_V8_THROW_VALUE_EXCEPTION(message); \
54+
return; \
55+
}
56+
57+
struct _php_v8_unbound_script_t {
58+
php_v8_isolate_t *php_v8_isolate;
59+
uint32_t isolate_handle;
60+
61+
v8::Persistent<v8::UnboundScript> *persistent;
62+
63+
zend_object std;
64+
};
65+
66+
PHP_MINIT_FUNCTION(php_v8_unbound_script);
67+
68+
#endif //PHP_V8_UNBOUND_SCRIPT_H

0 commit comments

Comments
 (0)