Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Unified Diff: src/compiler/ast-graph-builder.cc

Issue 717093002: Perform receiver patching for sloppy mode in high-level IR. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Minor fix. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/ia32/code-generator-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/ast-graph-builder.cc
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index 805afc5a3c515c1d28118e2160c6bca6424807be..4eb72a6d66598d63c00200ca2f5d9db9c2897720 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -72,13 +72,22 @@ bool AstGraphBuilder::CreateGraph() {
Environment env(this, scope, graph()->start());
set_environment(&env);
+ // Initialize the incoming context.
+ Node* outer_context = GetFunctionContext();
+ set_current_context(outer_context);
+
+ // Build receiver check for sloppy mode if necessary.
+ // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
+ Node* original_receiver = env.Lookup(scope->receiver());
+ Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver);
+ env.Bind(scope->receiver(), patched_receiver);
+
// Build node to initialize local function context.
Node* closure = GetFunctionClosure();
- Node* outer = GetFunctionContext();
- Node* inner = BuildLocalFunctionContext(outer, closure);
+ Node* inner_context = BuildLocalFunctionContext(outer_context, closure);
// Push top-level function scope for the function body.
- ContextScope top_context(this, scope, inner);
+ ContextScope top_context(this, scope, inner_context);
// Build the arguments object if it is used.
BuildArgumentsObject(scope->arguments());
@@ -1773,10 +1782,36 @@ Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) {
}
+Node* AstGraphBuilder::BuildPatchReceiverToGlobalProxy(Node* receiver) {
+ // Sloppy mode functions and builtins need to replace the receiver with the
+ // global proxy when called as functions (without an explicit receiver
+ // object). Otherwise there is nothing left to do here.
+ if (info()->strict_mode() != SLOPPY || info()->is_native()) return receiver;
+
+ // There is no need to perform patching if the receiver is never used. Note
+ // that scope predicates are purely syntactical, a call to eval might still
+ // inspect the receiver value.
+ if (!info()->scope()->uses_this() && !info()->scope()->inner_uses_this() &&
+ !info()->scope()->calls_sloppy_eval()) {
+ return receiver;
+ }
+
+ IfBuilder receiver_check(this);
+ Node* undefined = jsgraph()->UndefinedConstant();
+ Node* check = NewNode(javascript()->StrictEqual(), receiver, undefined);
+ receiver_check.If(check);
+ receiver_check.Then();
+ environment()->Push(BuildLoadGlobalProxy());
+ receiver_check.Else();
+ environment()->Push(receiver);
+ receiver_check.End();
+ return environment()->Pop();
+}
+
+
Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) {
int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
if (heap_slots <= 0) return context;
- set_current_context(context);
// Allocate a new local context.
const Operator* op = javascript()->CreateFunctionContext();
@@ -2069,6 +2104,14 @@ Node* AstGraphBuilder::BuildLoadGlobalObject() {
}
+Node* AstGraphBuilder::BuildLoadGlobalProxy() {
+ Node* global = BuildLoadGlobalObject();
+ Node* proxy =
+ BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset);
+ return proxy;
+}
+
+
Node* AstGraphBuilder::BuildToBoolean(Node* input) {
// TODO(titzer): this should be in a JSOperatorReducer.
switch (input->opcode()) {
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/ia32/code-generator-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698