Commit 30674bde authored by jochen's avatar jochen Committed by Commit bot

Introduce a compile method that takes context extensions

BUG=chromium:456192
R=yangguo@chromium.org
LOG=y

Review URL: https://codereview.chromium.org/910683002

Cr-Commit-Position: refs/heads/master@{#26530}
parent 7819c593
......@@ -1321,6 +1321,20 @@ class V8_EXPORT ScriptCompiler {
Isolate* isolate, Source* source,
CompileOptions options = kNoCompileOptions);
/**
* Compile a function for a given context. This is equivalent to running
*
* with (obj) {
* return function() { ... }
* }
*
* It is possible to specify multiple context extensions (obj in the above
* example).
*/
static Local<Function> CompileFunctionInContext(
Isolate* isolate, Source* source, Local<Context> context,
size_t context_extension_count, Local<Object> context_extensions[]);
private:
static Local<UnboundScript> CompileUnboundInternal(Isolate* isolate,
Source* source,
......
......@@ -1651,6 +1651,33 @@ Local<Script> ScriptCompiler::CompileModule(Isolate* v8_isolate, Source* source,
}
Local<Function> ScriptCompiler::CompileFunctionInContext(
Isolate* v8_isolate, Source* source, Local<Context> v8_context,
size_t context_extension_count, Local<Object> context_extensions[]) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
ON_BAILOUT(isolate, "v8::ScriptCompiler::CompileFunctionInContext()",
return Local<Function>());
LOG_API(isolate, "ScriptCompiler::CompileFunctionInContext()");
ENTER_V8(isolate);
i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
i::Handle<i::SharedFunctionInfo> outer_info(context->closure()->shared(),
isolate);
for (size_t i = 0; i < context_extension_count; ++i) {
i::Handle<i::JSObject> extension =
Utils::OpenHandle(*context_extensions[i]);
i::Handle<i::JSFunction> closure(context->closure(), isolate);
context = isolate->factory()->NewWithContext(closure, context, extension);
}
EXCEPTION_PREAMBLE(isolate);
i::MaybeHandle<i::JSFunction> result = i::Compiler::GetFunctionFromEval(
Utils::OpenHandle(*source->source_string), outer_info, context, i::SLOPPY,
i::NO_PARSE_RESTRICTION, 0 /* scope_position */);
has_pending_exception = result.is_null();
EXCEPTION_BAILOUT_CHECK(isolate, Local<Function>());
return Utils::ToLocal(result.ToHandleChecked());
}
ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript(
Isolate* v8_isolate, StreamedSource* source, CompileOptions options) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
......
......@@ -404,6 +404,61 @@ TEST(OptimizedCodeSharing) {
}
TEST(CompileFunctionInContext) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
LocalContext env;
CompileRun("var r = 10;");
v8::Local<v8::Object> math =
v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("Math")));
v8::ScriptCompiler::Source script_source(v8_str(
"a = PI * r * r;"
"x = r * cos(PI);"
"y = r * sin(PI / 2);"));
v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext(
CcTest::isolate(), &script_source, env.local(), 1, &math);
CHECK(!fun.IsEmpty());
fun->Call(env->Global(), 0, NULL);
CHECK(env->Global()->Has(v8_str("a")));
v8::Local<v8::Value> a = env->Global()->Get(v8_str("a"));
CHECK(a->IsNumber());
CHECK(env->Global()->Has(v8_str("x")));
v8::Local<v8::Value> x = env->Global()->Get(v8_str("x"));
CHECK(x->IsNumber());
CHECK(env->Global()->Has(v8_str("y")));
v8::Local<v8::Value> y = env->Global()->Get(v8_str("y"));
CHECK(y->IsNumber());
CHECK_EQ(314.1592653589793, a->NumberValue());
CHECK_EQ(-10.0, x->NumberValue());
CHECK_EQ(10.0, y->NumberValue());
}
TEST(CompileFunctionInContextComplex) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
LocalContext env;
CompileRun(
"var x = 1;"
"var y = 2;"
"var z = 4;"
"var a = {x: 8, y: 16};"
"var b = {x: 32};");
v8::Local<v8::Object> ext[2];
ext[0] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a")));
ext[1] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("b")));
v8::ScriptCompiler::Source script_source(v8_str("result = x + y + z"));
v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext(
CcTest::isolate(), &script_source, env.local(), 2, ext);
CHECK(!fun.IsEmpty());
fun->Call(env->Global(), 0, NULL);
CHECK(env->Global()->Has(v8_str("result")));
v8::Local<v8::Value> result = env->Global()->Get(v8_str("result"));
CHECK(result->IsNumber());
CHECK_EQ(52.0, result->NumberValue());
}
#ifdef ENABLE_DISASSEMBLER
static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
const char* property_name) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment