envChain_frame-evalWithBindings-with-eval.js (5934B)
1 // Verify the environment chain for Debugger.Frame described in 2 // js/src/vm/EnvironmentObject.h. 3 4 const g = newGlobal({ newCompartment: true }); 5 const dbg = Debugger(g); 6 7 dbg.onEnterFrame = frame => { 8 if (frame.script.displayName !== "target") { 9 return; 10 } 11 dbg.onEnterFrame = () => {}; 12 13 const bindings = { 14 bindings_prop: 50, 15 16 bindings_prop_var: 61, 17 bindings_prop_lexical: 71, 18 bindings_prop_unqualified: 81, 19 }; 20 21 const {envs, vars} = JSON.parse(frame.evalWithBindings(` 22 // Put direct eval to de-optimize lexical. 23 eval(""); 24 var qualified = 10; 25 unqualified = 20; 26 let lexical = 30; 27 this.prop = 40; 28 29 var bindings_prop_var = 60; 30 let bindings_prop_lexical = 70; 31 bindings_prop_unqualified = 80; 32 33 const vars = { 34 bindings_prop_var, 35 bindings_prop_lexical, 36 bindings_prop_unqualified, 37 }; 38 39 const envs = []; 40 let env = getInnerMostEnvironmentObject(); 41 while (env) { 42 envs.push({ 43 type: getEnvironmentObjectType(env) || "*global*", 44 qualified: !!Object.getOwnPropertyDescriptor(env, "qualified"), 45 unqualified: !!Object.getOwnPropertyDescriptor(env, "unqualified"), 46 lexical: !!Object.getOwnPropertyDescriptor(env, "lexical"), 47 prop: !!Object.getOwnPropertyDescriptor(env, "prop"), 48 bindings_prop: !!Object.getOwnPropertyDescriptor(env, "bindings_prop"), 49 50 bindings_prop_var: !!Object.getOwnPropertyDescriptor(env, "bindings_prop_var"), 51 bindings_prop_var_value: Object.getOwnPropertyDescriptor(env, "bindings_prop_var")?.value, 52 bindings_prop_lexical: !!Object.getOwnPropertyDescriptor(env, "bindings_prop_lexical"), 53 bindings_prop_lexical_value: Object.getOwnPropertyDescriptor(env, "bindings_prop_lexical")?.value, 54 bindings_prop_unqualified: !!Object.getOwnPropertyDescriptor(env, "bindings_prop_unqualified"), 55 bindings_prop_unqualified_value: Object.getOwnPropertyDescriptor(env, "bindings_prop_unqualified")?.value, 56 }); 57 58 env = getEnclosingEnvironmentObject(env); 59 } 60 JSON.stringify({envs, vars}); 61 `, bindings).return); 62 63 assertEq(vars.bindings_prop_var, 60, 64 "qualified var should read the value set by the declaration"); 65 assertEq(vars.bindings_prop_lexical, 70, 66 "lexical should read the value set by the declaration"); 67 assertEq(vars.bindings_prop_unqualified, 80, 68 "unqualified name should read the value set by the assignment"); 69 70 assertEq(bindings.bindings_prop_var, 61, 71 "the original bindings property must not be overwritten for var"); 72 assertEq(bindings.bindings_prop_lexical, 71, 73 "the original bindings property must not be overwritten for lexical"); 74 assertEq(bindings.bindings_prop_unqualified, 81, 75 "the original bindings property must not be overwritten for unqualified"); 76 77 assertEq(envs.length, 5); 78 79 let i = 0, env; 80 81 env = envs[i]; i++; 82 assertEq(env.type, "BlockLexicalEnvironmentObject"); 83 assertEq(env.qualified, false); 84 assertEq(env.unqualified, false); 85 assertEq(env.lexical, true, "lexical must live in the BlockLexicalEnvironmentObject"); 86 assertEq(env.prop, false); 87 88 assertEq(env.bindings_prop_var, false); 89 assertEq(env.bindings_prop_lexical, true, 90 "lexical must live in the BlockLexicalEnvironmentObject even if it conflicts with the bindings object property"); 91 assertEq(env.bindings_prop_lexical_value, 70); 92 assertEq(env.bindings_prop_unqualified, false); 93 94 env = envs[i]; i++; 95 assertEq(env.type, "WithEnvironmentObject"); 96 assertEq(env.qualified, false); 97 assertEq(env.unqualified, false); 98 assertEq(env.lexical, false); 99 assertEq(env.prop, false); 100 assertEq(env.bindings_prop, true, "bindings property must live in the with env for bindings"); 101 102 assertEq(env.bindings_prop_var, true, 103 "bindings property must live in the with env for bindings"); 104 assertEq(env.bindings_prop_var_value, 60, 105 "bindings property must be overwritten for var"); 106 assertEq(env.bindings_prop_lexical, true, 107 "bindings property must live in the with env for bindings"); 108 assertEq(env.bindings_prop_lexical_value, 71, 109 "bindings property must not be overwritten for lexical"); 110 assertEq(env.bindings_prop_unqualified, true, 111 "bindings property must live in the with env for bindings"); 112 assertEq(env.bindings_prop_unqualified_value, 80, 113 "bindings property must not be overwritten for unqualified"); 114 115 env = envs[i]; i++; 116 assertEq(env.type, "[DebugProxy] CallObject"); 117 assertEq(env.qualified, true, "qualified var must live in the CallObject"); 118 assertEq(env.unqualified, false); 119 assertEq(env.lexical, false); 120 assertEq(env.prop, false); 121 assertEq(env.bindings_prop, false); 122 123 assertEq(env.bindings_prop_var, true, 124 "qualified var binding must be created in the CallObject even if it conflicts with the bindings object property"); 125 assertEq(env.bindings_prop_var_value, undefined, 126 "qualified var value must not be set if it conflicts with the bindings object property"); 127 assertEq(env.bindings_prop_lexical, false); 128 assertEq(env.bindings_prop_unqualified, false); 129 130 env = envs[i]; i++; 131 assertEq(env.type, "[DebugProxy] GlobalLexicalEnvironmentObject"); 132 assertEq(env.qualified, false); 133 assertEq(env.unqualified, false); 134 assertEq(env.lexical, false); 135 assertEq(env.prop, false); 136 assertEq(env.bindings_prop, false); 137 138 assertEq(env.bindings_prop_var, false); 139 assertEq(env.bindings_prop_lexical, false); 140 assertEq(env.bindings_prop_unqualified, false); 141 142 env = envs[i]; i++; 143 assertEq(env.type, "*global*"); 144 assertEq(env.qualified, false); 145 assertEq(env.unqualified, true, "unqualified name must live in the global"); 146 assertEq(env.lexical, false); 147 assertEq(env.prop, true, "this property must live in the global"); 148 assertEq(env.bindings_prop, false); 149 150 assertEq(env.bindings_prop_var, false); 151 assertEq(env.bindings_prop_lexical, false); 152 assertEq(env.bindings_prop_unqualified, false); 153 }; 154 155 g.eval(` 156 function target() { 157 } 158 target(); 159 `);